From 27f057778fd8f43ce3ee7a418dc104299e4f8abf Mon Sep 17 00:00:00 2001 From: Morten Nobel-Joergensen Date: Mon, 14 May 2018 22:29:59 +0200 Subject: [PATCH 01/22] Improve CMake - set C++14 required - disable extensions --- CMakeLists.txt | 4 +++- version-history.md | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ee3aed9..eec88422 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,9 @@ if ("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}") "$ cmake ${CMAKE_CURRENT_SOURCE_DIR}") endif () -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) set (CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") diff --git a/version-history.md b/version-history.md index d042babb..d21010e6 100644 --- a/version-history.md +++ b/version-history.md @@ -1,5 +1,6 @@ ## Version history + * 1.1.1 * 1.1.0 Shadowmap support. Mesh indices 32 bit option (now uses uint32_t for mesh indices instead of uint16_t). Fixed Camera::screenPointToRay for scaled/offset viewport. * 1.0.10 Update ImGui to 1.60. Procedural skybox. Face culling option in Shader. Two sided rendering. * 1.0.9 Better support for stencil operations using shaders From 291ff6ad2876658161c5deafad04f2e1a4027226 Mon Sep 17 00:00:00 2001 From: Morten Nobel-Joergensen Date: Sat, 19 May 2018 22:50:49 +0200 Subject: [PATCH 02/22] Version tick --- include/sre/Renderer.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/sre/Renderer.hpp b/include/sre/Renderer.hpp index e75f82f3..a9993494 100755 --- a/include/sre/Renderer.hpp +++ b/include/sre/Renderer.hpp @@ -71,7 +71,7 @@ namespace sre { ~Renderer(); static constexpr int sre_version_major = 1; static constexpr int sre_version_minor = 1; - static constexpr int sre_version_point = 0; + static constexpr int sre_version_point = 1; glm::ivec2 getWindowSize(); // Return the current size of the window From 04d49c75955134d0543e42e39478d9598afc4697 Mon Sep 17 00:00:00 2001 From: Morten Nobel-Joergensen Date: Sat, 19 May 2018 22:59:48 +0200 Subject: [PATCH 03/22] Better distinguish between shader compile errors and compile warnings --- src/sre/Shader.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/sre/Shader.cpp b/src/sre/Shader.cpp index 9b5df2c0..ad99d0dc 100755 --- a/src/sre/Shader.cpp +++ b/src/sre/Shader.cpp @@ -118,7 +118,7 @@ namespace sre { return sstream.str(); } - void logCurrentCompileInfo(GLuint &shader, GLenum type, vector &errors, const std::string& source, const std::string name) { + void logCurrentCompileInfo(GLuint &shader, GLenum type, vector &errors, const std::string& source, const std::string name, bool compileSuccess) { GLint logSize = 0; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize); if (logSize > 1){ // log size of 1 is empty, since it includes \0 @@ -148,10 +148,13 @@ namespace sre { typeStr = std::string("Unknown error type: ") + std::to_string(type); break; } - - LOG_ERROR("Shader compile error in %s (%s): %s", name.c_str(), typeStr.c_str(), errorLog.data()); + if (compileSuccess){ + LOG_WARNING("Shader compile warning in %s (%s): %s", name.c_str(), typeStr.c_str(), errorLog.data()); + } else { + LOG_ERROR("Shader compile error in %s (%s): %s", name.c_str(), typeStr.c_str(), errorLog.data()); + } errors.push_back(std::string(errorLog.data())+"##"+std::to_string(type)); - if (Renderer::instance->getRenderStats().frame <= 1){ + if (Renderer::instance->getRenderStats().frame <= 1 && !compileSuccess){ std::cout << source << std::endl; } } @@ -993,7 +996,7 @@ namespace sre { GLint success = 0; glGetShaderiv(shader, GL_COMPILE_STATUS, &success); - logCurrentCompileInfo(shader, type, errors, source_, resource.value); + logCurrentCompileInfo(shader, type, errors, source_, resource.value, success==1); return success == 1; } From 9a9336b39c8f9acfee965b282319290085afabbe Mon Sep 17 00:00:00 2001 From: Morten Nobel-Joergensen Date: Sat, 19 May 2018 23:00:42 +0200 Subject: [PATCH 04/22] ImGUI v1.61 ImGUI TextEditor --- include/TextEditor.h | 12 +- include/imconfig.h | 19 +- include/imgui.h | 216 +++-- include/imgui_internal.h | 163 ++-- include/stb_textedit.h | 2 +- src/imgui/TextEditor.cpp | 105 +- src/imgui/imgui.cpp | 1975 +++++++++++++++++++++----------------- src/imgui/imgui_draw.cpp | 60 +- test/imgui_demo.cpp | 222 +++-- 9 files changed, 1635 insertions(+), 1139 deletions(-) diff --git a/include/TextEditor.h b/include/TextEditor.h index 6d6eec9c..3b5e9290 100755 --- a/include/TextEditor.h +++ b/include/TextEditor.h @@ -11,7 +11,7 @@ #include "imgui.h" /** - * https://github.com/BalazsJako/ImGuiColorTextEdit (commit 6c69c306da0afb6c0b7ea51ec504aa0aae348aad) + * https://github.com/BalazsJako/ImGuiColorTextEdit (commit 1fbba2fe8da83139a39789ea4ef8ca3077143b79) * * MIT License * @@ -65,6 +65,13 @@ class TextEditor Max }; + enum class SelectionMode + { + Normal, + Word, + Line + }; + struct Breakpoint { int mLine; @@ -222,7 +229,7 @@ class TextEditor void SetSelectionStart(const Coordinates& aPosition); void SetSelectionEnd(const Coordinates& aPosition); - void SetSelection(const Coordinates& aStart, const Coordinates& aEnd, bool awordmode = false); + void SetSelection(const Coordinates& aStart, const Coordinates& aEnd, SelectionMode aMode = SelectionMode::Normal); void SelectWordUnderCursor(); void SelectAll(); bool HasSelection() const; @@ -329,6 +336,7 @@ class TextEditor bool mWordSelectionMode; bool mTextChanged; int mColorRangeMin, mColorRangeMax; + SelectionMode mSelectionMode; Palette mPalette; LanguageDefinition mLanguageDefinition; diff --git a/include/imconfig.h b/include/imconfig.h index 70987f5e..57db8497 100755 --- a/include/imconfig.h +++ b/include/imconfig.h @@ -5,14 +5,17 @@ //----------------------------------------------------------------------------- // A) You may edit imconfig.h (and not overwrite it when updating imgui, or maintain a patch/branch with your modifications to imconfig.h) // B) or add configuration directives in your own file and compile with #define IMGUI_USER_CONFIG "myfilename.h" -// C) Many compile-time options have an effect on data structures. They need defined consistently _everywhere_ imgui.h is included, -// not only for the imgui*.cpp compilation units. Defining those options in imconfig.h will ensure they correctly get used everywhere. +// If you do so you need to make sure that configuration settings are defined consistently _everywhere_ dear imgui is used, which include +// the imgui*.cpp files but also _any_ of your code that uses imgui. This is because some compile-time options have an affect on data structures. +// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts. +// Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using. //----------------------------------------------------------------------------- #pragma once //---- Define assertion handler. Defaults to calling assert(). //#define IM_ASSERT(_EXPR) MyAssert(_EXPR) +//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts //---- Define attributes of all API symbols declarations, e.g. for DLL under Windows. //#define IMGUI_API __declspec( dllexport ) @@ -21,16 +24,16 @@ //---- Don't define obsolete functions/enums names. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names #define IMGUI_DISABLE_OBSOLETE_FUNCTIONS -//---- Don't implement default handlers for Windows (so as not to link with certain functions) -//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // Don't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. -//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // Don't use and link with ImmGetContext/ImmSetCompositionWindow. - //---- Don't implement demo windows functionality (ShowDemoWindow()/ShowStyleEditor()/ShowUserGuide() methods will be empty) //---- It is very strongly recommended to NOT disable the demo windows during development. Please read the comments in imgui_demo.cpp. //#define IMGUI_DISABLE_DEMO_WINDOWS -//---- Don't implement ImFormatString(), ImFormatStringV() so you can reimplement them yourself. -//#define IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS +//---- Don't implement some functions to reduce linkage requirements. +//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. +//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] Don't implement default IME handler. Won't use and link with ImmGetContext/ImmSetCompositionWindow. +//#define IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself if you don't want to link with vsnprintf. +//#define IMGUI_DISABLE_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 wrapper so you can implement them yourself. Declare your prototypes in imconfig.h. +//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free(). You will need to call ImGui::SetAllocatorFunctions(). //---- Include imgui_user.h at the end of imgui.h as a convenience //#define IMGUI_INCLUDE_IMGUI_USER_H diff --git a/include/imgui.h b/include/imgui.h index 90411301..f4cbbec7 100755 --- a/include/imgui.h +++ b/include/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.60 WIP +// dear imgui, v1.61 // (headers) // See imgui.cpp file for documentation. @@ -16,25 +16,25 @@ #include "imconfig.h" #endif -#include // FLT_MAX -#include // va_list -#include // ptrdiff_t, NULL -#include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp +#include // FLT_MAX +#include // va_list +#include // ptrdiff_t, NULL +#include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp -#define IMGUI_VERSION "1.60 WIP" +// Version +#define IMGUI_VERSION "1.61" +#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert)) -// Define attributes of all API symbols declarations, e.g. for DLL under Windows. +// Define attributes of all API symbols declarations (e.g. for DLL under Windows) #ifndef IMGUI_API #define IMGUI_API #endif -// Define assertion handler. +// Helpers #ifndef IM_ASSERT #include -#define IM_ASSERT(_EXPR) assert(_EXPR) +#define IM_ASSERT(_EXPR) assert(_EXPR) #endif - -// Helpers #if defined(__clang__) || defined(__GNUC__) #define IM_FMTARGS(FMT) __attribute__((format(printf, FMT, FMT+1))) // Apply printf-style warnings to user functions. #define IM_FMTLIST(FMT) __attribute__((format(printf, FMT, 0))) @@ -60,7 +60,7 @@ struct ImDrawVert; // A single vertex (20 bytes by default, ove struct ImFont; // Runtime data for a single font within a parent ImFontAtlas struct ImFontAtlas; // Runtime data for multiple fonts, bake multiple fonts into a single texture, TTF/OTF font loader struct ImFontConfig; // Configuration data when adding a font or merging fonts -struct ImColor; // Helper functions to create a color that can be converted to either u32 or float4 +struct ImColor; // Helper functions to create a color that can be converted to either u32 or float4 (*obsolete* please avoid using) struct ImGuiIO; // Main configuration and I/O between your application and ImGui struct ImGuiOnceUponAFrame; // Simple helper for running a block of code not more than once a frame, used by IMGUI_ONCE_UPON_A_FRAME macro struct ImGuiStorage; // Simple custom key value storage @@ -72,16 +72,15 @@ struct ImGuiSizeCallbackData; // Structure used to constraint window size struct ImGuiListClipper; // Helper to manually clip large list of items struct ImGuiPayload; // User data payload for drag and drop operations struct ImGuiContext; // ImGui context (opaque) - #ifndef ImTextureID typedef void* ImTextureID; // User data to identify a texture (this is whatever to you want it to be! read the FAQ about ImTextureID in imgui.cpp) #endif // Typedefs and Enumerations (declared as int for compatibility with old C++ and to not pollute the top of this file) -typedef unsigned int ImU32; // 32-bit unsigned integer (typically used to store packed colors) typedef unsigned int ImGuiID; // Unique ID used by widgets (typically hashed from a stack of string) typedef unsigned short ImWchar; // Character for keyboard input/display typedef int ImGuiCol; // enum: a color identifier for styling // enum ImGuiCol_ +typedef int ImGuiDataType; // enum: a primary data type // enum ImGuiDataType_ typedef int ImGuiDir; // enum: a cardinal direction // enum ImGuiDir_ typedef int ImGuiCond; // enum: a condition for Set*() // enum ImGuiCond_ typedef int ImGuiKey; // enum: a key identifier (ImGui-side enum) // enum ImGuiKey_ @@ -95,8 +94,8 @@ typedef int ImGuiBackendFlags; // flags: for io.BackendFlags typedef int ImGuiColorEditFlags; // flags: for ColorEdit*(), ColorPicker*() // enum ImGuiColorEditFlags_ typedef int ImGuiColumnsFlags; // flags: for *Columns*() // enum ImGuiColumnsFlags_ typedef int ImGuiConfigFlags; // flags: for io.ConfigFlags // enum ImGuiConfigFlags_ -typedef int ImGuiDragDropFlags; // flags: for *DragDrop*() // enum ImGuiDragDropFlags_ typedef int ImGuiComboFlags; // flags: for BeginCombo() // enum ImGuiComboFlags_ +typedef int ImGuiDragDropFlags; // flags: for *DragDrop*() // enum ImGuiDragDropFlags_ typedef int ImGuiFocusedFlags; // flags: for IsWindowFocused() // enum ImGuiFocusedFlags_ typedef int ImGuiHoveredFlags; // flags: for IsItemHovered() etc. // enum ImGuiHoveredFlags_ typedef int ImGuiInputTextFlags; // flags: for InputText*() // enum ImGuiInputTextFlags_ @@ -105,35 +104,43 @@ typedef int ImGuiTreeNodeFlags; // flags: for TreeNode*(),CollapsingHeader() typedef int ImGuiWindowFlags; // flags: for Begin*() // enum ImGuiWindowFlags_ typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data); typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data); + +// Scalar data types +typedef signed int ImS32; // 32-bit signed integer == int +typedef unsigned int ImU32; // 32-bit unsigned integer (often used to store packed colors) #if defined(_MSC_VER) && !defined(__clang__) -typedef unsigned __int64 ImU64; // 64-bit unsigned integer +typedef signed __int64 ImS64; // 64-bit signed integer +typedef unsigned __int64 ImU64; // 64-bit unsigned integer #else -typedef unsigned long long ImU64; // 64-bit unsigned integer +typedef signed long long ImS64; // 64-bit signed integer +typedef unsigned long long ImU64; // 64-bit unsigned integer #endif +// 2d vector struct ImVec2 { - float x, y; - ImVec2() { x = y = 0.0f; } + float x, y; + ImVec2() { x = y = 0.0f; } ImVec2(float _x, float _y) { x = _x; y = _y; } - float operator[] (size_t idx) const { IM_ASSERT(idx <= 1); return (&x)[idx]; } // We very rarely use this [] operator, the assert overhead is fine. -#ifdef IM_VEC2_CLASS_EXTRA // Define constructor and implicit cast operators in imconfig.h to convert back<>forth from your math types and ImVec2. - IM_VEC2_CLASS_EXTRA + float operator[] (size_t i) const { IM_ASSERT(i <= 1); return (&x)[i]; } // We very rarely use this [] operator, the assert overhead is fine. +#ifdef IM_VEC2_CLASS_EXTRA + IM_VEC2_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec2. #endif }; +// 4d vector (often used to store floating-point colors) struct ImVec4 { - float x, y, z, w; - ImVec4() { x = y = z = w = 0.0f; } + float x, y, z, w; + ImVec4() { x = y = z = w = 0.0f; } ImVec4(float _x, float _y, float _z, float _w) { x = _x; y = _y; z = _z; w = _w; } -#ifdef IM_VEC4_CLASS_EXTRA // Define constructor and implicit cast operators in imconfig.h to convert back<>forth from your math types and ImVec4. - IM_VEC4_CLASS_EXTRA +#ifdef IM_VEC4_CLASS_EXTRA + IM_VEC4_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec4. #endif }; // ImGui end-user API -// In a namespace so that user can add extra functions in a separate file (e.g. Value() helpers for your vector or common types) +// In a namespace so that user can add extra functions in your own separate file (please don't modify imgui.cpp/.h) namespace ImGui { // Context creation and access @@ -143,6 +150,7 @@ namespace ImGui IMGUI_API void DestroyContext(ImGuiContext* ctx = NULL); // NULL = destroy current context IMGUI_API ImGuiContext* GetCurrentContext(); IMGUI_API void SetCurrentContext(ImGuiContext* ctx); + IMGUI_API bool DebugCheckVersionAndDataLayout(const char* version_str, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_drawvert); // Main IMGUI_API ImGuiIO& GetIO(); @@ -169,7 +177,7 @@ namespace ImGui // Windows // (Begin = push window to the stack and start appending to it. End = pop window from the stack. You may append multiple times to the same window during the same frame) // Begin()/BeginChild() return false to indicate the window being collapsed or fully clipped, so you may early out and omit submitting anything to the window. - // However you need to always call a matching End()/EndChild() for a Begin()/BeginChild() call, regardless of its return value (this is due to legacy reason and is inconsistent with BeginMenu/EndMenu, BeginPopup/EndPopup and other functions where the End call should only be called if the corresponding Begin function returned true.) + // You need to always call a matching End()/EndChild() for a Begin()/BeginChild() call, regardless of its return value (this is due to legacy reason and is inconsistent with BeginMenu/EndMenu, BeginPopup/EndPopup and other functions where the End call should only be called if the corresponding Begin function returned true.) // Passing 'bool* p_open != NULL' shows a close widget in the upper-right corner of the window, which when clicking will set the boolean to false. // Use child windows to introduce independent scrolling/clipping regions within a host window. Child windows can embed their own child. IMGUI_API bool Begin(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); @@ -231,7 +239,7 @@ namespace ImGui IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val); IMGUI_API void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val); IMGUI_API void PopStyleVar(int count = 1); - IMGUI_API const ImVec4& GetStyleColorVec4(ImGuiCol idx); // retrieve style color as stored in ImGuiStyle structure. use to feed back into PushStyleColor(), otherwhise use GetColorU32() to get style color with style alpha baked in. + IMGUI_API const ImVec4& GetStyleColorVec4(ImGuiCol idx); // retrieve style color as stored in ImGuiStyle structure. use to feed back into PushStyleColor(), otherwise use GetColorU32() to get style color with style alpha baked in. IMGUI_API ImFont* GetFont(); // get current font IMGUI_API float GetFontSize(); // get current font size (= height in pixels) of current font with current scale applied IMGUI_API ImVec2 GetFontTexUvWhitePixel(); // get UV coordinate for a while pixel, useful to draw custom shapes via the ImDrawList API @@ -334,43 +342,52 @@ namespace ImGui // Widgets: Drags (tip: ctrl+click on a drag box to input with keyboard. manually input values aren't clamped, can go off-bounds) // For all the Float2/Float3/Float4/Int2/Int3/Int4 versions of every functions, note that a 'float v[X]' function argument is the same as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible. You can pass address of your first element out of a contiguous set, e.g. &myvector.x + // Adjust format string to decorate the value with a prefix, a suffix, or adapt the editing and display precision e.g. "%.3f" -> 1.234; "%5.2f secs" -> 01.23 secs; "Biscuit: %.0f" -> Biscuit: 1; etc. // Speed are per-pixel of mouse movement (v_speed=0.2f: mouse needs to move by 5 pixels to increase value by 1). For gamepad/keyboard navigation, minimum speed is Max(v_speed, minimum_step_at_given_precision). - IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); // If v_min >= v_max we have no bound - IMGUI_API bool DragFloat2(const char* label, float v[2], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); - IMGUI_API bool DragFloat3(const char* label, float v[3], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); - IMGUI_API bool DragFloat4(const char* label, float v[4], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); - IMGUI_API bool DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", const char* display_format_max = NULL, float power = 1.0f); - IMGUI_API bool DragInt(const char* label, int* v, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); // If v_min >= v_max we have no bound - IMGUI_API bool DragInt2(const char* label, int v[2], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); - IMGUI_API bool DragInt3(const char* label, int v[3], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); - IMGUI_API bool DragInt4(const char* label, int v[4], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); - IMGUI_API bool DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f", const char* display_format_max = NULL); + IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", float power = 1.0f); // If v_min >= v_max we have no bound + IMGUI_API bool DragFloat2(const char* label, float v[2], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", float power = 1.0f); + IMGUI_API bool DragFloat3(const char* label, float v[3], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", float power = 1.0f); + IMGUI_API bool DragFloat4(const char* label, float v[4], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", float power = 1.0f); + IMGUI_API bool DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* format = "%.3f", const char* format_max = NULL, float power = 1.0f); + IMGUI_API bool DragInt(const char* label, int* v, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d"); // If v_min >= v_max we have no bound + IMGUI_API bool DragInt2(const char* label, int v[2], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d"); + IMGUI_API bool DragInt3(const char* label, int v[3], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d"); + IMGUI_API bool DragInt4(const char* label, int v[4], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d"); + IMGUI_API bool DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* format = "%d", const char* format_max = NULL); + IMGUI_API bool DragScalar(const char* label, ImGuiDataType data_type, void* v, float v_speed, const void* v_min = NULL, const void* v_max = NULL, const char* format = NULL, float power = 1.0f); + IMGUI_API bool DragScalarN(const char* label, ImGuiDataType data_type, void* v, int components, float v_speed, const void* v_min = NULL, const void* v_max = NULL, const char* format = NULL, float power = 1.0f); // Widgets: Input with Keyboard IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL); IMGUI_API bool InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size = ImVec2(0,0), ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL); - IMGUI_API bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0); - IMGUI_API bool InputFloat2(const char* label, float v[2], int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0); - IMGUI_API bool InputFloat3(const char* label, float v[3], int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0); - IMGUI_API bool InputFloat4(const char* label, float v[4], int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0); + IMGUI_API bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, const char* format = "%.3f", ImGuiInputTextFlags extra_flags = 0); + IMGUI_API bool InputFloat2(const char* label, float v[2], const char* format = "%.3f", ImGuiInputTextFlags extra_flags = 0); + IMGUI_API bool InputFloat3(const char* label, float v[3], const char* format = "%.3f", ImGuiInputTextFlags extra_flags = 0); + IMGUI_API bool InputFloat4(const char* label, float v[4], const char* format = "%.3f", ImGuiInputTextFlags extra_flags = 0); IMGUI_API bool InputInt(const char* label, int* v, int step = 1, int step_fast = 100, ImGuiInputTextFlags extra_flags = 0); IMGUI_API bool InputInt2(const char* label, int v[2], ImGuiInputTextFlags extra_flags = 0); IMGUI_API bool InputInt3(const char* label, int v[3], ImGuiInputTextFlags extra_flags = 0); IMGUI_API bool InputInt4(const char* label, int v[4], ImGuiInputTextFlags extra_flags = 0); - IMGUI_API bool InputDouble(const char* label, double* v, double step = 0.0f, double step_fast = 0.0f, const char* display_format = "%.6f", ImGuiInputTextFlags extra_flags = 0); + IMGUI_API bool InputDouble(const char* label, double* v, double step = 0.0f, double step_fast = 0.0f, const char* format = "%.6f", ImGuiInputTextFlags extra_flags = 0); + IMGUI_API bool InputScalar(const char* label, ImGuiDataType data_type, void* v, const void* step = NULL, const void* step_fast = NULL, const char* format = NULL, ImGuiInputTextFlags extra_flags = 0); + IMGUI_API bool InputScalarN(const char* label, ImGuiDataType data_type, void* v, int components, const void* step = NULL, const void* step_fast = NULL, const char* format = NULL, ImGuiInputTextFlags extra_flags = 0); // Widgets: Sliders (tip: ctrl+click on a slider to input with keyboard. manually input values aren't clamped, can go off-bounds) - IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); // adjust display_format to decorate the value with a prefix or a suffix for in-slider labels or unit display. Use power!=1.0 for logarithmic sliders - IMGUI_API bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); - IMGUI_API bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); - IMGUI_API bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); + // Adjust format string to decorate the value with a prefix, a suffix, or adapt the editing and display precision e.g. "%.3f" -> 1.234; "%5.2f secs" -> 01.23 secs; "Biscuit: %.0f" -> Biscuit: 1; etc. + IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f); // adjust format to decorate the value with a prefix or a suffix for in-slider labels or unit display. Use power!=1.0 for power curve sliders + IMGUI_API bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* format = "%.3f", float power = 1.0f); + IMGUI_API bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* format = "%.3f", float power = 1.0f); + IMGUI_API bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* format = "%.3f", float power = 1.0f); IMGUI_API bool SliderAngle(const char* label, float* v_rad, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f); - IMGUI_API bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format = "%.0f"); - IMGUI_API bool SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* display_format = "%.0f"); - IMGUI_API bool SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* display_format = "%.0f"); - IMGUI_API bool SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* display_format = "%.0f"); - IMGUI_API bool VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); - IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format = "%.0f"); + IMGUI_API bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* format = "%d"); + IMGUI_API bool SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* format = "%d"); + IMGUI_API bool SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* format = "%d"); + IMGUI_API bool SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* format = "%d"); + IMGUI_API bool SliderScalar(const char* label, ImGuiDataType data_type, void* v, const void* v_min, const void* v_max, const char* format = NULL, float power = 1.0f); + IMGUI_API bool SliderScalarN(const char* label, ImGuiDataType data_type, void* v, int components, const void* v_min, const void* v_max, const char* format = NULL, float power = 1.0f); + IMGUI_API bool VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f); + IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* format = "%d"); + IMGUI_API bool VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType data_type, void* v, const void* v_min, const void* v_max, const char* format = NULL, float power = 1.0f); // Widgets: Color Editor/Picker (tip: the ColorEdit* functions have a little colored preview square that can be left-clicked to open a picker, and right-clicked to open an option menu.) // Note that a 'float v[X]' function argument is the same as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible. You can the pass the address of a first float element out of a contiguous structure, e.g. &myvector.x @@ -406,9 +423,9 @@ namespace ImGui IMGUI_API bool Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); // "bool* p_selected" point to the selection state (read-write), as a convenient helper. IMGUI_API bool ListBox(const char* label, int* current_item, const char* const items[], int items_count, int height_in_items = -1); IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); - IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0,0)); // use if you want to reimplement ListBox() will custom data or interactions. make sure to call ListBoxFooter() afterwards. + IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0,0)); // use if you want to reimplement ListBox() will custom data or interactions. if the function return true, you can output elements then call ListBoxFooter() afterwards. IMGUI_API bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // " - IMGUI_API void ListBoxFooter(); // terminate the scrolling region + IMGUI_API void ListBoxFooter(); // terminate the scrolling region. only call ListBoxFooter() if ListBoxHeader() returned true! // Widgets: Value() Helpers. Output single value in "name: value" format (tip: freely declare more in your code to handle your types. you can add functions to the ImGui namespace) IMGUI_API void Value(const char* prefix, bool b); @@ -516,7 +533,7 @@ namespace ImGui // Inputs IMGUI_API int GetKeyIndex(ImGuiKey imgui_key); // map ImGuiKey_* values into user's key index. == io.KeyMap[key] - IMGUI_API bool IsKeyDown(int user_key_index); // is key being held. == io.KeysDown[user_key_index]. note that imgui doesn't know the semantic of each entry of io.KeyDown[]. Use your own indices/enums according to how your backend/engine stored them into KeyDown[]! + IMGUI_API bool IsKeyDown(int user_key_index); // is key being held. == io.KeysDown[user_key_index]. note that imgui doesn't know the semantic of each entry of io.KeysDown[]. Use your own indices/enums according to how your backend/engine stored them into io.KeysDown[]! IMGUI_API bool IsKeyPressed(int user_key_index, bool repeat = true); // was key pressed (went from !Down to Down). if repeat=true, uses io.KeyRepeatDelay / KeyRepeatRate IMGUI_API bool IsKeyReleased(int user_key_index); // was key released (went from Down to !Down).. IMGUI_API int GetKeyPressedAmount(int key_index, float repeat_delay, float rate); // uses provided repeat rate/delay. return a count, most often 0 or 1 but might be >1 if RepeatRate is small enough that DeltaTime > RepeatRate @@ -541,6 +558,14 @@ namespace ImGui IMGUI_API const char* GetClipboardText(); IMGUI_API void SetClipboardText(const char* text); + // Settings/.Ini Utilities + // The disk functions are automatically called if io.IniFilename != NULL (default is "imgui.ini"). + // Set io.IniFilename to NULL to load/save manually. Read io.WantSaveIniSettings description about handling .ini saving manually. + IMGUI_API void LoadIniSettingsFromDisk(const char* ini_filename); // call after CreateContext() and before the first call to NewFrame(). NewFrame() automatically calls LoadIniSettingsFromDisk(io.IniFilename). + IMGUI_API void LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size=0); // call after CreateContext() and before the first call to NewFrame() to provide .ini data from your own data source. + IMGUI_API void SaveIniSettingsToDisk(const char* ini_filename); + IMGUI_API const char* SaveIniSettingsToMemory(size_t* out_ini_size = NULL); // return a zero-terminated string with the .ini data which you can save by your own mean. call when io.WantSaveIniSettings is set, then save data by your own mean and clear io.WantSaveIniSettings. + // Memory Utilities // All those functions are not reliant on the current context. // If you reload the contents of imgui.cpp at runtime, you may need to call SetCurrentContext() + SetAllocatorFunctions() again. @@ -695,10 +720,22 @@ enum ImGuiDragDropFlags_ ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect // For peeking ahead and inspecting the payload before delivery. }; -// Standard Drag and Drop payload types. You can define you own payload types using 12-characters long strings. Types starting with '_' are defined by Dear ImGui. +// Standard Drag and Drop payload types. You can define you own payload types using short strings. Types starting with '_' are defined by Dear ImGui. #define IMGUI_PAYLOAD_TYPE_COLOR_3F "_COL3F" // float[3]: Standard type for colors, without alpha. User code may use this type. #define IMGUI_PAYLOAD_TYPE_COLOR_4F "_COL4F" // float[4]: Standard type for colors. User code may use this type. +// A primary data type +enum ImGuiDataType_ +{ + ImGuiDataType_S32, // int + ImGuiDataType_U32, // unsigned int + ImGuiDataType_S64, // long long, __int64 + ImGuiDataType_U64, // unsigned long long, unsigned __int64 + ImGuiDataType_Float, // float + ImGuiDataType_Double, // double + ImGuiDataType_COUNT +}; + // A cardinal direction enum ImGuiDir_ { @@ -738,14 +775,14 @@ enum ImGuiKey_ }; // [BETA] Gamepad/Keyboard directional navigation -// Keyboard: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays. +// Keyboard: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeysDown[] + io.KeyMap[] arrays. // Gamepad: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad to enable. Back-end: set ImGuiBackendFlags_HasGamepad and fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame(). // Read instructions in imgui.cpp for more details. Download PNG/PSD at goo.gl/9LgVZW. enum ImGuiNavInput_ { // Gamepad Mapping - ImGuiNavInput_Activate, // activate / open / toggle / tweak value // e.g. Circle (PS4), A (Xbox), A (Switch), Space (Keyboard) - ImGuiNavInput_Cancel, // cancel / close / exit // e.g. Cross (PS4), B (Xbox), B (Switch), Escape (Keyboard) + ImGuiNavInput_Activate, // activate / open / toggle / tweak value // e.g. Cross (PS4), A (Xbox), A (Switch), Space (Keyboard) + ImGuiNavInput_Cancel, // cancel / close / exit // e.g. Circle (PS4), B (Xbox), B (Switch), Escape (Keyboard) ImGuiNavInput_Input, // text input / on-screen keyboard // e.g. Triang.(PS4), Y (Xbox), X (Switch), Return (Keyboard) ImGuiNavInput_Menu, // tap: toggle menu / hold: focus, move, resize // e.g. Square (PS4), X (Xbox), Y (Switch), Alt (Keyboard) ImGuiNavInput_DpadLeft, // move / tweak / resize window (w/ PadMenu) // e.g. D-pad Left/Right/Up/Down (Gamepads), Arrow keys (Keyboard) @@ -762,7 +799,7 @@ enum ImGuiNavInput_ ImGuiNavInput_TweakFast, // faster tweaks // e.g. R1 or R2 (PS4), RB or RT (Xbox), R or ZL (Switch) // [Internal] Don't use directly! This is used internally to differentiate keyboard from gamepad inputs for behaviors that require to differentiate them. - // Keyboard behavior that have no corresponding gamepad mapping (e.g. CTRL+TAB) will be directly reading from io.KeyDown[] instead of io.NavInputs[]. + // Keyboard behavior that have no corresponding gamepad mapping (e.g. CTRL+TAB) will be directly reading from io.KeysDown[] instead of io.NavInputs[]. ImGuiNavInput_KeyMenu_, // toggle menu // = io.KeyAlt ImGuiNavInput_KeyLeft_, // move left // = Arrow keys ImGuiNavInput_KeyRight_, // move right @@ -775,7 +812,7 @@ enum ImGuiNavInput_ // Configuration flags stored in io.ConfigFlags. Set by user/application. enum ImGuiConfigFlags_ { - ImGuiConfigFlags_NavEnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. NewFrame() will automatically fill io.NavInputs[] based on io.KeyDown[]. + ImGuiConfigFlags_NavEnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. NewFrame() will automatically fill io.NavInputs[] based on io.KeysDown[]. ImGuiConfigFlags_NavEnableGamepad = 1 << 1, // Master gamepad navigation enable flag. This is mostly to instruct your imgui back-end to fill io.NavInputs[]. Back-end also needs to set ImGuiBackendFlags_HasGamepad. ImGuiConfigFlags_NavEnableSetMousePos = 1 << 2, // Instruct navigation to move the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is awkward. Will update io.MousePos and set io.WantSetMousePos=true. If enabled you MUST honor io.WantSetMousePos requests in your binding, otherwise ImGui will react as if the mouse is jumping around back and forth. ImGuiConfigFlags_NavNoCaptureKeyboard = 1 << 3, // Instruct navigation to not set the io.WantCaptureKeyboard flag with io.NavActive is set. @@ -790,9 +827,9 @@ enum ImGuiConfigFlags_ // Back-end capabilities flags stored in io.BackendFlags. Set by imgui_impl_xxx or custom back-end. enum ImGuiBackendFlags_ { - ImGuiBackendFlags_HasGamepad = 1 << 0, // Back-end has a connected gamepad. - ImGuiBackendFlags_HasMouseCursors = 1 << 1, // Back-end can honor GetMouseCursor() values and change the OS cursor shape. - ImGuiBackendFlags_HasSetMousePos = 1 << 2 // Back-end can honor io.WantSetMousePos and reposition the mouse (only used if ImGuiConfigFlags_NavEnableSetMousePos is set). + ImGuiBackendFlags_HasGamepad = 1 << 0, // Back-end supports and has a connected gamepad. + ImGuiBackendFlags_HasMouseCursors = 1 << 1, // Back-end supports reading GetMouseCursor() to change the OS cursor shape. + ImGuiBackendFlags_HasSetMousePos = 1 << 2 // Back-end supports io.WantSetMousePos requests to reposition the OS mouse position (only used if ImGuiConfigFlags_NavEnableSetMousePos is set). }; // Enumeration for PushStyleColor() / PopStyleColor() @@ -836,10 +873,10 @@ enum ImGuiCol_ ImGuiCol_PlotHistogram, ImGuiCol_PlotHistogramHovered, ImGuiCol_TextSelectedBg, - ImGuiCol_ModalWindowDarkening, // darken/colorize entire screen behind a modal window, when one is active + ImGuiCol_ModalWindowDarkening, // Darken/colorize entire screen behind a modal window, when one is active ImGuiCol_DragDropTarget, - ImGuiCol_NavHighlight, // gamepad/keyboard: current highlighted item - ImGuiCol_NavWindowingHighlight, // gamepad/keyboard: when holding NavMenu to focus/move/resize windows + ImGuiCol_NavHighlight, // Gamepad/keyboard: current highlighted item + ImGuiCol_NavWindowingHighlight, // Gamepad/keyboard: when holding NavMenu to focus/move/resize windows ImGuiCol_COUNT // Obsolete names (will be removed) @@ -980,7 +1017,7 @@ struct ImGuiStyle float GrabRounding; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f,0.5f) for horizontally+vertically centered. ImVec2 DisplayWindowPadding; // Window positions are clamped to be visible within the display area by at least this amount. Only covers regular windows. - ImVec2 DisplaySafeAreaPadding; // 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. + 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). May be removed later. bool AntiAliasedLines; // Enable anti-aliasing on lines/borders. Disable if you are really tight on CPU/GPU. bool AntiAliasedFill; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) @@ -1000,11 +1037,11 @@ struct ImGuiIO //------------------------------------------------------------------ ImGuiConfigFlags ConfigFlags; // = 0 // See ImGuiConfigFlags_ enum. Set by user/application. Gamepad/keyboard navigation options, etc. - ImGuiBackendFlags BackendFlags; // = 0 // Set ImGuiBackendFlags_ enum. Set by imgui_impl_xxx files or custom back-end. + ImGuiBackendFlags BackendFlags; // = 0 // Set ImGuiBackendFlags_ enum. Set by imgui_impl_xxx files or custom back-end to communicate features supported by the back-end. ImVec2 DisplaySize; // // Display size, in pixels. For clamping windows positions. float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds. - float IniSavingRate; // = 5.0f // Maximum time between saving positions/sizes to .ini file, in seconds. - const char* IniFilename; // = "imgui.ini" // Path to .ini file. NULL to disable .ini saving. + float IniSavingRate; // = 5.0f // Minimum time between saving positions/sizes to .ini file, in seconds. + const char* IniFilename; // = "imgui.ini" // Path to .ini file. Set NULL to disable automatic .ini loading/saving, if e.g. you want to manually load/save from memory. const char* LogFilename; // = "imgui_log.txt" // Path to .log file (default parameter to ImGui::LogToFile when no file is specified). float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds. float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels. @@ -1042,9 +1079,12 @@ struct ImGuiIO void* ImeWindowHandle; // (Windows) Set this to your HWND to get automatic IME cursor positioning. #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - // [OBSOLETE] Rendering function, will be automatically called in Render(). Please call your rendering function yourself now! You can obtain the ImDrawData* by calling ImGui::GetDrawData() after Render(). - // See example applications if you are unsure of how to implement this. + // [OBSOLETE] Rendering function, will be automatically called in Render(). Please call your rendering function yourself now! + // You can obtain the ImDrawData* by calling ImGui::GetDrawData() after Render(). See example applications if you are unsure of how to implement this. void (*RenderDrawListsFn)(ImDrawData* data); +#else + // This is only here to keep ImGuiIO the same size, so that IMGUI_DISABLE_OBSOLETE_FUNCTIONS can exceptionally be used outside of imconfig.h. + void* RenderDrawListsFnDummy; #endif //------------------------------------------------------------------ @@ -1053,8 +1093,8 @@ struct ImGuiIO ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX,-FLT_MAX) if mouse is unavailable (on another screen, etc.) bool MouseDown[5]; // Mouse buttons: left, right, middle + extras. ImGui itself mostly only uses left button (BeginPopupContext** are using right button). Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. - float MouseWheel; // Mouse wheel: 1 unit scrolls about 5 lines text. - float MouseWheelH; // Mouse wheel (Horizontal). Most users don't have a mouse with an horizontal wheel, may not be filled by all back-ends. + float MouseWheel; // Mouse wheel Vertical: 1 unit scrolls about 5 lines text. + float MouseWheelH; // Mouse wheel Horizontal. Most users don't have a mouse with an horizontal wheel, may not be filled by all back-ends. bool MouseDrawCursor; // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). bool KeyCtrl; // Keyboard modifier pressed: Control bool KeyShift; // Keyboard modifier pressed: Shift @@ -1077,6 +1117,7 @@ struct ImGuiIO bool WantCaptureKeyboard; // When io.WantCaptureKeyboard is true, imgui will use the keyboard inputs, do not dispatch them to your main game/application (in both cases, always pass keyboard inputs to imgui). (e.g. InputText active, or an imgui window is focused and navigation is enabled, etc.). bool WantTextInput; // Mobile/console: when io.WantTextInput is true, you may display an on-screen keyboard. This is set by ImGui when it wants textual keyboard input to happen (e.g. when a InputText widget is active). bool WantSetMousePos; // MousePos has been altered, back-end should reposition mouse on next frame. Set only when ImGuiConfigFlags_NavEnableSetMousePos flag is enabled. + bool WantSaveIniSettings; // When manual .ini load/save is active (io.IniFilename == NULL), this will be set to notify your application that you can call SaveIniSettingsToMemory() and save yourself. IMPORTANT: You need to clear io.WantSaveIniSettings yourself. bool NavActive; // Directional navigation is currently allowed (will handle ImGuiKey_NavXXX events) = a window is focused and it doesn't use the ImGuiWindowFlags_NoNavInputs flag. bool NavVisible; // Directional navigation is visible and allowed (will handle ImGuiKey_NavXXX events). float Framerate; // Application framerate estimation, in frame per second. Solely for convenience. Rolling average estimation based on IO.DeltaTime over 120 frames @@ -1115,6 +1156,11 @@ struct ImGuiIO #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS namespace ImGui { + // OBSOLETED in 1.61 (from Apr 2018) + bool InputFloat(const char* label, float* v, float step, float step_fast, int decimal_precision, ImGuiInputTextFlags extra_flags = 0); // Use the 'const char* format' version instead of 'decimal_precision'! + bool InputFloat2(const char* label, float v[2], int decimal_precision, ImGuiInputTextFlags extra_flags = 0); + bool InputFloat3(const char* label, float v[3], int decimal_precision, ImGuiInputTextFlags extra_flags = 0); + bool InputFloat4(const char* label, float v[4], int decimal_precision, ImGuiInputTextFlags extra_flags = 0); // OBSOLETED in 1.60 (from Dec 2017) static inline bool IsAnyWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_AnyWindow); } static inline bool IsAnyWindowHovered() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); } @@ -1212,7 +1258,7 @@ inline void* operator new(size_t, ImNewDummy, void* ptr) { return ptr; } inline void operator delete(void*, ImNewDummy, void*) {} // This is only required so we can use the symetrical new() #define IM_PLACEMENT_NEW(_PTR) new(ImNewDummy(), _PTR) #define IM_NEW(_TYPE) new(ImNewDummy(), ImGui::MemAlloc(sizeof(_TYPE))) _TYPE -template void IM_DELETE(T*& p) { if (p) { p->~T(); ImGui::MemFree(p); p = NULL; } } +template void IM_DELETE(T* p) { if (p) { p->~T(); ImGui::MemFree(p); } } // Helper: Execute a block of code at maximum once a frame. Convenient if you want to quickly create an UI within deep-nested code that runs multiple times every frame. // Usage: static ImGuiOnceUponAFrame oaf; if (oaf) ImGui::Text("This will be called only once per frame"); @@ -1368,7 +1414,7 @@ struct ImGuiSizeCallbackData struct ImGuiPayload { // Members - const void* Data; // Data (copied and owned by dear imgui) + void* Data; // Data (copied and owned by dear imgui) int DataSize; // Data size // [Internal] @@ -1531,7 +1577,7 @@ enum ImDrawListFlags_ // This is the low-level list of polygons that ImGui functions are filling. At the end of the frame, all command lists are passed to your ImGuiIO::RenderDrawListFn function for rendering. // Each ImGui window contains its own ImDrawList. You can use ImGui::GetWindowDrawList() to access the current window draw list and draw custom primitives. // You can interleave normal ImGui:: calls and adding primitives to the current draw list. -// All positions are generally in pixel coordinates (top-left at (0,0), bottom-right at io.DisplaySize), however you are totally free to apply whatever transformation matrix to want to the data (if you apply such transformation you'll want to apply it to ClipRect as well) +// All positions are generally in pixel coordinates (top-left at (0,0), bottom-right at io.DisplaySize), but you are totally free to apply whatever transformation matrix to want to the data (if you apply such transformation you'll want to apply it to ClipRect as well) // Important: Primitives are always added to the list and not culled (culling is done at higher-level by ImGui:: functions), if you use this API a lot consider coarse culling your drawn objects. struct ImDrawList { @@ -1582,17 +1628,17 @@ struct ImDrawList IMGUI_API void AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,0), const ImVec2& uv_c = ImVec2(1,1), const ImVec2& uv_d = ImVec2(0,1), ImU32 col = 0xFFFFFFFF); IMGUI_API void AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, float rounding, int rounding_corners = ImDrawCornerFlags_All); IMGUI_API void AddPolyline(const ImVec2* points, const int num_points, ImU32 col, bool closed, float thickness); - IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col); + IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col); // Note: Anti-aliased filling requires points to be in clockwise order. IMGUI_API void AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0); - // Stateful path API, add points then finish with PathFill() or PathStroke() + // Stateful path API, add points then finish with PathFillConvex() or PathStroke() inline void PathClear() { _Path.resize(0); } inline void PathLineTo(const ImVec2& pos) { _Path.push_back(pos); } inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || memcmp(&_Path[_Path.Size-1], &pos, 8) != 0) _Path.push_back(pos); } - inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col); PathClear(); } + inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col); PathClear(); } // Note: Anti-aliased filling requires points to be in clockwise order. inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness); PathClear(); } IMGUI_API void PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments = 10); - IMGUI_API void PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle + IMGUI_API void PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle IMGUI_API void PathBezierCurveTo(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, int num_segments = 0); IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, int rounding_corners_flags = ImDrawCornerFlags_All); @@ -1686,7 +1732,7 @@ enum ImFontAtlasFlags_ // 2. Call GetTexDataAsAlpha8() or GetTexDataAsRGBA32() to build and retrieve pixels data. // 3. Upload the pixels data into a texture within your graphics system. // 4. Call SetTexID(my_tex_id); and pass the pointer/identifier to your texture. This value will be passed back to you during rendering to identify the texture. -// IMPORTANT: If you pass a 'glyph_ranges' array to AddFont*** functions, you need to make sure that your array persist up until the ImFont is build (when calling GetTextData*** or Build()). We only copy the pointer, not the data. +// IMPORTANT: If you pass a 'glyph_ranges' array to AddFont*** functions, you need to make sure that your array persist up until the ImFont is build (when calling GetTexData*** or Build()). We only copy the pointer, not the data. struct ImFontAtlas { IMGUI_API ImFontAtlas(); diff --git a/include/imgui_internal.h b/include/imgui_internal.h index 0af53025..7ec9aa9a 100755 --- a/include/imgui_internal.h +++ b/include/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.60 +// dear imgui, v1.61 // (internals) // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! @@ -13,6 +13,7 @@ #endif #include // FILE* +#include // NULL, malloc, free, qsort, atoi, atof #include // sqrtf, fabsf, fmodf, powf, floorf, ceilf, cosf, sinf #include // INT_MIN, INT_MAX @@ -82,7 +83,7 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit ImGui context pointe #define IM_PI 3.14159265358979323846f #ifdef _WIN32 -#define IM_NEWLINE "\r\n" // Play it nice with Windows users (2018: Notepad _still_ doesn't display files properly when they use Unix-style carriage returns) +#define IM_NEWLINE "\r\n" // Play it nice with Windows users (2018/05 news: Microsoft announced that Notepad will finally display Unix-style carriage returns!) #else #define IM_NEWLINE "\n" #endif @@ -96,9 +97,10 @@ IMGUI_API int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, cons // Helpers: Misc IMGUI_API ImU32 ImHash(const void* data, int data_size, ImU32 seed = 0); // Pass data_size==0 for zero-terminated strings -IMGUI_API void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, int* out_file_size = NULL, int padding_bytes = 0); +IMGUI_API void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, size_t* out_file_size = NULL, int padding_bytes = 0); IMGUI_API FILE* ImFileOpen(const char* filename, const char* file_open_mode); -static inline bool ImCharIsSpace(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; } +static inline bool ImCharIsBlankA(char c) { return c == ' ' || c == '\t'; } +static inline bool ImCharIsBlankW(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; } static inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; } static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; } @@ -117,11 +119,17 @@ IMGUI_API const char* ImStrchrRange(const char* str_begin, const char* str_end IMGUI_API int ImStrlenW(const ImWchar* str); IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end); +IMGUI_API void ImStrTrimBlanks(char* str); IMGUI_API int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) IM_FMTARGS(3); IMGUI_API int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) IM_FMTLIST(3); - -// Helpers: Math -// We are keeping those not leaking to the user by default, in the case the user has implicit cast operators between ImVec2 and its own types (when IM_VEC2_CLASS_EXTRA is defined) +IMGUI_API const char* ImParseFormatFindStart(const char* format); +IMGUI_API const char* ImParseFormatFindEnd(const char* format); +IMGUI_API const char* ImParseFormatTrimDecorations(const char* format, char* buf, int buf_size); +IMGUI_API int ImParseFormatPrecision(const char* format, int default_value); + +// Helpers: ImVec2/ImVec4 operators +// We are keeping those disabled by default so they don't leak in user space, to allow user enabling implicit cast operators between ImVec2 and their own types (using IM_VEC2_CLASS_EXTRA etc.) +// We unfortunately don't have a unary- operator for ImVec2 because this would needs to be defined inside the class itself. #ifdef IMGUI_DEFINE_MATH_OPERATORS static inline ImVec2 operator*(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x*rhs, lhs.y*rhs); } static inline ImVec2 operator/(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x/rhs, lhs.y/rhs); } @@ -138,26 +146,40 @@ static inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) static inline ImVec4 operator*(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x*rhs.x, lhs.y*rhs.y, lhs.z*rhs.z, lhs.w*rhs.w); } #endif -static inline int ImMin(int lhs, int rhs) { return lhs < rhs ? lhs : rhs; } -static inline int ImMax(int lhs, int rhs) { return lhs >= rhs ? lhs : rhs; } -static inline float ImMin(float lhs, float rhs) { return lhs < rhs ? lhs : rhs; } -static inline float ImMax(float lhs, float rhs) { return lhs >= rhs ? lhs : rhs; } +// Helpers: Maths +// - Wrapper for standard libs functions. (Note that imgui_demo.cpp does _not_ use them to keep the code easy to copy) +#ifndef IMGUI_DISABLE_MATH_FUNCTIONS +static inline float ImFabs(float x) { return fabsf(x); } +static inline float ImSqrt(float x) { return sqrtf(x); } +static inline float ImPow(float x, float y) { return powf(x, y); } +static inline double ImPow(double x, double y) { return pow(x, y); } +static inline float ImFmod(float x, float y) { return fmodf(x, y); } +static inline double ImFmod(double x, double y) { return fmod(x, y); } +static inline float ImCos(float x) { return cosf(x); } +static inline float ImSin(float x) { return sinf(x); } +static inline float ImAcos(float x) { return acosf(x); } +static inline float ImAtan2(float y, float x) { return atan2f(y, x); } +static inline double ImAtof(const char* s) { return atof(s); } +static inline float ImFloorStd(float x) { return floorf(x); } // we already uses our own ImFloor() { return (float)(int)v } internally so the standard one wrapper is named differently (it's used by stb_truetype) +static inline float ImCeil(float x) { return ceilf(x); } +#endif +// - ImMin/ImMax/ImClamp/ImLerp/ImSwap are used by widgets which support for variety of types: signed/unsigned int/long long float/double, using templates here but we could also redefine them 6 times +template static inline T ImMin(T lhs, T rhs) { return lhs < rhs ? lhs : rhs; } +template static inline T ImMax(T lhs, T rhs) { return lhs >= rhs ? lhs : rhs; } +template static inline T ImClamp(T v, T mn, T mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } +template static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * t); } +template static inline void ImSwap(T& a, T& b) { T tmp = a; a = b; b = tmp; } +// - Misc maths helpers static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x < rhs.x ? lhs.x : rhs.x, lhs.y < rhs.y ? lhs.y : rhs.y); } static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x >= rhs.x ? lhs.x : rhs.x, lhs.y >= rhs.y ? lhs.y : rhs.y); } -static inline int ImClamp(int v, int mn, int mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } -static inline float ImClamp(float v, float mn, float mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } -static inline ImVec2 ImClamp(const ImVec2& f, const ImVec2& mn, ImVec2 mx) { return ImVec2(ImClamp(f.x,mn.x,mx.x), ImClamp(f.y,mn.y,mx.y)); } -static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; } -static inline void ImSwap(int& a, int& b) { int tmp = a; a = b; b = tmp; } -static inline void ImSwap(float& a, float& b) { float tmp = a; a = b; b = tmp; } -static inline int ImLerp(int a, int b, float t) { return (int)(a + (b - a) * t); } -static inline float ImLerp(float a, float b, float t) { return a + (b - a) * t; } +static inline ImVec2 ImClamp(const ImVec2& v, const ImVec2& mn, ImVec2 mx) { return ImVec2((v.x < mn.x) ? mn.x : (v.x > mx.x) ? mx.x : v.x, (v.y < mn.y) ? mn.y : (v.y > mx.y) ? mx.y : v.y); } static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, float t) { return ImVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t); } static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); } static inline ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t) { return ImVec4(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t); } +static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; } static inline float ImLengthSqr(const ImVec2& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y; } static inline float ImLengthSqr(const ImVec4& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y + lhs.z*lhs.z + lhs.w*lhs.w; } -static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = lhs.x*lhs.x + lhs.y*lhs.y; if (d > 0.0f) return 1.0f / sqrtf(d); return fail_value; } +static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = lhs.x*lhs.x + lhs.y*lhs.y; if (d > 0.0f) return 1.0f / ImSqrt(d); return fail_value; } static inline float ImFloor(float f) { return (float)(int)f; } static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)v.x, (float)(int)v.y); } static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; } @@ -244,14 +266,6 @@ enum ImGuiPlotType ImGuiPlotType_Histogram }; -enum ImGuiDataType -{ - ImGuiDataType_Int, - ImGuiDataType_Float, - ImGuiDataType_Double, - ImGuiDataType_COUNT -}; - enum ImGuiInputSource { ImGuiInputSource_None = 0, @@ -322,11 +336,10 @@ struct IMGUI_API ImRect void Add(const ImRect& r) { if (Min.x > r.Min.x) Min.x = r.Min.x; if (Min.y > r.Min.y) Min.y = r.Min.y; if (Max.x < r.Max.x) Max.x = r.Max.x; if (Max.y < r.Max.y) Max.y = r.Max.y; } void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; } void Expand(const ImVec2& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; } - void Translate(const ImVec2& v) { Min.x += v.x; Min.y += v.y; Max.x += v.x; Max.y += v.y; } + void Translate(const ImVec2& d) { Min.x += d.x; Min.y += d.y; Max.x += d.x; Max.y += d.y; } void ClipWith(const ImRect& r) { Min = ImMax(Min, r.Min); Max = ImMin(Max, r.Max); } // Simple version, may lead to an inverted rectangle, which is fine for Contains/Overlaps test but not for display. void ClipWithFull(const ImRect& r) { Min = ImClamp(Min, r.Min, r.Max); Max = ImClamp(Max, r.Min, r.Max); } // Full version, ensure both points are fully clipped. void Floor() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; } - void FixInverted() { if (Min.x > Max.x) ImSwap(Min.x, Max.x); if (Min.y > Max.y) ImSwap(Min.y, Max.y); } bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; } }; @@ -415,9 +428,9 @@ struct ImGuiSettingsHandler { const char* TypeName; // Short description stored in .ini file. Disallowed characters: '[' ']' ImGuiID TypeHash; // == ImHash(TypeName, 0, 0) - void* (*ReadOpenFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, const char* name); - void (*ReadLineFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, void* entry, const char* line); - void (*WriteAllFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* out_buf); + void* (*ReadOpenFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, const char* name); // Read: Called when entering into a new ini entry e.g. "[Window][Name]" + void (*ReadLineFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, void* entry, const char* line); // Read: Called for every line of text within an ini entry + void (*WriteAllFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* out_buf); // Write: Output every entries into 'out_buf' void* UserData; ImGuiSettingsHandler() { memset(this, 0, sizeof(*this)); } @@ -529,10 +542,11 @@ struct ImGuiNextWindowData ImVec2 SizeVal; ImVec2 ContentSizeVal; bool CollapsedVal; - ImRect SizeConstraintRect; // Valid if 'SetNextWindowSizeConstraint' is true + ImRect SizeConstraintRect; ImGuiSizeCallback SizeCallback; void* SizeCallbackUserData; float BgAlphaVal; + ImVec2 MenuBarOffsetMinVal; // This is not exposed publicly, so we don't clear it. ImGuiNextWindowData() { @@ -544,6 +558,7 @@ struct ImGuiNextWindowData SizeCallback = NULL; SizeCallbackUserData = NULL; BgAlphaVal = FLT_MAX; + MenuBarOffsetMinVal = ImVec2(0.0f, 0.0f); } void Clear() @@ -662,37 +677,36 @@ struct ImGuiContext ImGuiID ScalarAsInputTextId; // Temporary text input when CTRL+clicking on a slider, etc. ImGuiColorEditFlags ColorEditOptions; // Store user options for color edit widgets ImVec4 ColorPickerRef; - float DragCurrentValue; // Currently dragged value, always float, not rounded by end-user precision settings - ImVec2 DragLastMouseDelta; + bool DragCurrentAccumDirty; + float DragCurrentAccum; // Accumulator for dragging modification. Always high-precision, not rounded by end-user precision settings float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio - float DragSpeedScaleSlow; - float DragSpeedScaleFast; ImVec2 ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage? int TooltipOverrideCount; ImVector PrivateClipboard; // If no custom clipboard handler is defined - ImVec2 OsImePosRequest, OsImePosSet; // Cursor position request & last passed to the OS Input Method Editor + ImVec2 PlatformImePos, PlatformImeLastPos; // Cursor position request & last passed to the OS Input Method Editor // Settings bool SettingsLoaded; - float SettingsDirtyTimer; // Save .ini Settings on disk when time reaches zero - ImVector SettingsWindows; // .ini settings for ImGuiWindow + float SettingsDirtyTimer; // Save .ini Settings to memory when time reaches zero + ImGuiTextBuffer SettingsIniData; // In memory .ini settings ImVector SettingsHandlers; // List of .ini settings handlers + ImVector SettingsWindows; // ImGuiWindow .ini settings entries (parsed from the last loaded .ini file and maintained on saving) // Logging bool LogEnabled; FILE* LogFile; // If != NULL log to stdout/ file - ImGuiTextBuffer* LogClipboard; // Else log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators. + ImGuiTextBuffer LogClipboard; // Accumulation buffer when log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators. int LogStartDepth; int LogAutoExpandMaxDepth; // Misc - float FramerateSecPerFrame[120]; // calculate estimate of framerate for user + float FramerateSecPerFrame[120]; // Calculate estimate of framerate for user over the last 2 seconds. int FramerateSecPerFrameIdx; float FramerateSecPerFrameAccum; - int WantCaptureMouseNextFrame; // explicit capture via CaptureInputs() sets those flags + int WantCaptureMouseNextFrame; // Explicit capture via CaptureKeyboardFromApp()/CaptureMouseFromApp() sets those flags int WantCaptureKeyboardNextFrame; int WantTextInputNextFrame; - char TempBuffer[1024*3+1]; // temporary text buffer + char TempBuffer[1024*3+1]; // Temporary text buffer ImGuiContext(ImFontAtlas* shared_font_atlas) : OverlayDrawList(NULL) { @@ -767,21 +781,18 @@ struct ImGuiContext ScalarAsInputTextId = 0; ColorEditOptions = ImGuiColorEditFlags__OptionsDefault; - DragCurrentValue = 0.0f; - DragLastMouseDelta = ImVec2(0.0f, 0.0f); + DragCurrentAccumDirty = false; + DragCurrentAccum = 0.0f; DragSpeedDefaultRatio = 1.0f / 100.0f; - DragSpeedScaleSlow = 1.0f / 100.0f; - DragSpeedScaleFast = 10.0f; ScrollbarClickDeltaToGrabCenter = ImVec2(0.0f, 0.0f); TooltipOverrideCount = 0; - OsImePosRequest = OsImePosSet = ImVec2(-1.0f, -1.0f); + PlatformImePos = PlatformImeLastPos = ImVec2(FLT_MAX, FLT_MAX); SettingsLoaded = false; SettingsDirtyTimer = 0.0f; LogEnabled = false; LogFile = NULL; - LogClipboard = NULL; LogStartDepth = 0; LogAutoExpandMaxDepth = 2; @@ -832,7 +843,7 @@ struct IMGUI_API ImGuiDrawContext int NavLayerActiveMask; // Which layer have been written to (result from previous frame) int NavLayerActiveMaskNext; // Which layer have been written to (buffer for current frame) bool MenuBarAppending; // FIXME: Remove this - float MenuBarOffsetX; + ImVec2 MenuBarOffset; // MenuBarOffset.x is sort of equivalent of a per-layer CursorPos.x, saved/restored as we switch to the menu bar. The only situation when MenuBarOffset.y is > 0 if when (SafeAreaPadding.y > FramePadding.y), often used on TVs. ImVector ChildWindows; ImGuiStorage* StateStorage; ImGuiLayoutType LayoutType; @@ -870,7 +881,7 @@ struct IMGUI_API ImGuiDrawContext NavLayerCurrent = 0; NavLayerCurrentMask = 1 << 0; MenuBarAppending = false; - MenuBarOffsetX = 0.0f; + MenuBarOffset = ImVec2(0.0f, 0.0f); StateStorage = NULL; LayoutType = ParentLayoutType = ImGuiLayoutType_Vertical; ItemWidth = 0.0f; @@ -891,14 +902,12 @@ struct IMGUI_API ImGuiWindow char* Name; ImGuiID ID; // == ImHash(Name) ImGuiWindowFlags Flags; // See enum ImGuiWindowFlags_ - ImVec2 PosFloat; - ImVec2 Pos; // Position rounded-up to nearest pixel + ImVec2 Pos; // Position (always rounded-up to nearest pixel) ImVec2 Size; // Current size (==SizeFull or collapsed title bar size) ImVec2 SizeFull; // Size when non collapsed ImVec2 SizeFullAtLastBegin; // Copy of SizeFull at the end of Begin. This is the reference value we'll use on the next frame to decide if we need scrollbars. ImVec2 SizeContents; // Size of contents (== extents reach of the drawing cursor) from previous frame. Include decoration, window title, border, menu, etc. ImVec2 SizeContentsExplicit; // Size of contents explicitly set by the user via SetNextWindowContentSize() - ImRect ContentsRegionRect; // Maximum visible content position in window coordinates. ~~ (SizeContentsExplicit ? SizeContentsExplicit : Size - ScrollbarSizes) - CursorStartPos, per axis ImVec2 WindowPadding; // Window padding at the time of begin. float WindowRounding; // Window rounding at the time of begin. float WindowBorderSize; // Window border size at the time of begin. @@ -907,8 +916,8 @@ struct IMGUI_API ImGuiWindow ImVec2 Scroll; ImVec2 ScrollTarget; // target scroll position. stored as cursor position with scrolling canceled out, so the highest point is always 0.0f. (FLT_MAX for no change) ImVec2 ScrollTargetCenterRatio; // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered + ImVec2 ScrollbarSizes; // Size taken by scrollbars on each axis bool ScrollbarX, ScrollbarY; - ImVec2 ScrollbarSizes; bool Active; // Set to true on Begin(), unless Collapsed bool WasActive; bool WriteAccessed; // Set to true when any widget access the current window @@ -926,24 +935,27 @@ struct IMGUI_API ImGuiWindow int AutoFitChildAxises; ImGuiDir AutoPosLastDirection; int HiddenFrames; - ImGuiCond SetWindowPosAllowFlags; // store condition flags for next SetWindowPos() call. - ImGuiCond SetWindowSizeAllowFlags; // store condition flags for next SetWindowSize() call. - ImGuiCond SetWindowCollapsedAllowFlags; // store condition flags for next SetWindowCollapsed() call. + ImGuiCond SetWindowPosAllowFlags; // store acceptable condition flags for SetNextWindowPos() use. + ImGuiCond SetWindowSizeAllowFlags; // store acceptable condition flags for SetNextWindowSize() use. + ImGuiCond SetWindowCollapsedAllowFlags; // store acceptable condition flags for SetNextWindowCollapsed() use. ImVec2 SetWindowPosVal; // store window position when using a non-zero Pivot (position set needs to be processed when we know the window size) ImVec2 SetWindowPosPivot; // store window pivot for positioning. ImVec2(0,0) when positioning from top-left corner; ImVec2(0.5f,0.5f) for centering; ImVec2(1,1) for bottom right. ImGuiDrawContext DC; // Temporary per-window data, reset at the beginning of the frame ImVector IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack - ImRect ClipRect; // = DrawList->clip_rect_stack.back(). Scissoring / clipping rectangle. x1, y1, x2, y2. - ImRect WindowRectClipped; // = WindowRect just after setup in Begin(). == window->Rect() for root window. - ImRect InnerRect, InnerClipRect; + ImRect ClipRect; // Current clipping rectangle. = DrawList->clip_rect_stack.back(). Scissoring / clipping rectangle. x1, y1, x2, y2. + ImRect OuterRectClipped; // = WindowRect just after setup in Begin(). == window->Rect() for root window. + ImRect InnerMainRect, InnerClipRect; + ImRect ContentsRegionRect; // FIXME: This is currently confusing/misleading. Maximum visible content position ~~ Pos + (SizeContentsExplicit ? SizeContentsExplicit : Size - ScrollbarSizes) - CursorStartPos, per axis int LastFrameActive; float ItemWidthDefault; ImGuiMenuColumns MenuColumns; // Simplified columns storage for menu items ImGuiStorage StateStorage; ImVector ColumnsStorage; - float FontWindowScale; // Scale multiplier per-window - ImDrawList* DrawList; + float FontWindowScale; // User scale multiplier per-window + + ImDrawList* DrawList; // == &DrawListInst (for backward compatibility reason with code using imgui_internal.h we keep this a pointer) + ImDrawList DrawListInst; ImGuiWindow* ParentWindow; // If we are a child _or_ popup window, this is pointing to our parent. Otherwise NULL. ImGuiWindow* RootWindow; // Point to ourself or first ancestor that is not a child window. ImGuiWindow* RootWindowForTitleBarHighlight; // Point to ourself or first ancestor which will display TitleBgActive color when this window is active. @@ -977,7 +989,7 @@ struct IMGUI_API ImGuiWindow float CalcFontSize() const { return GImGui->FontBaseSize * FontWindowScale; } float TitleBarHeight() const { return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontSize() + GImGui->Style.FramePadding.y * 2.0f; } ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight())); } - float MenuBarHeight() const { return (Flags & ImGuiWindowFlags_MenuBar) ? CalcFontSize() + GImGui->Style.FramePadding.y * 2.0f : 0.0f; } + float MenuBarHeight() const { return (Flags & ImGuiWindowFlags_MenuBar) ? DC.MenuBarOffset.y + CalcFontSize() + GImGui->Style.FramePadding.y * 2.0f : 0.0f; } ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight(); return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight()); } }; @@ -1020,6 +1032,7 @@ namespace ImGui IMGUI_API void NewFrameUpdateHoveredWindowAndCaptureFlags(); IMGUI_API void MarkIniSettingsDirty(); + IMGUI_API void MarkIniSettingsDirty(ImGuiWindow* window); IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(const char* type_name); IMGUI_API ImGuiWindowSettings* FindWindowSettings(ImGuiID id); @@ -1052,6 +1065,7 @@ namespace ImGui IMGUI_API bool IsPopupOpen(ImGuiID id); IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags); IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_tooltip = true); + IMGUI_API ImGuiWindow* GetFrontMostPopupModal(); IMGUI_API void NavInitWindow(ImGuiWindow* window, bool force_reinit); IMGUI_API void NavMoveRequestCancel(); @@ -1093,19 +1107,11 @@ namespace ImGui IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0,0), ImGuiButtonFlags flags = 0); IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos, float radius); - IMGUI_API bool SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, ImGuiSliderFlags flags = 0); - IMGUI_API bool SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* display_format, float power); - IMGUI_API bool SliderIntN(const char* label, int* v, int components, int v_min, int v_max, const char* display_format); - - IMGUI_API bool DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_speed, float v_min, float v_max, int decimal_precision, float power); - IMGUI_API bool DragFloatN(const char* label, float* v, int components, float v_speed, float v_min, float v_max, const char* display_format, float power); - IMGUI_API bool DragIntN(const char* label, int* v, int components, float v_speed, int v_min, int v_max, const char* display_format); + IMGUI_API bool DragBehavior(ImGuiID id, ImGuiDataType data_type, void* v, float v_speed, const void* v_min, const void* v_max, const char* format, float power); + IMGUI_API bool SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* v, const void* v_min, const void* v_max, const char* format, float power, ImGuiSliderFlags flags = 0); IMGUI_API bool InputTextEx(const char* label, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback = NULL, void* user_data = NULL); - IMGUI_API bool InputFloatN(const char* label, float* v, int components, int decimal_precision, ImGuiInputTextFlags extra_flags); - IMGUI_API bool InputIntN(const char* label, int* v, int components, ImGuiInputTextFlags extra_flags); - IMGUI_API bool InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags); - IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision); + IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* data_ptr, const char* format); IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags); IMGUI_API void ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags); @@ -1116,9 +1122,6 @@ namespace ImGui IMGUI_API void PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size); - IMGUI_API int ParseFormatPrecision(const char* fmt, int default_value); - IMGUI_API float RoundScalar(float value, int decimal_precision); - // Shade functions (write over already created vertices) IMGUI_API void ShadeVertsLinearColorGradientKeepAlpha(ImDrawVert* vert_start, ImDrawVert* vert_end, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1); IMGUI_API void ShadeVertsLinearAlphaGradientForLeftToRightText(ImDrawVert* vert_start, ImDrawVert* vert_end, float gradient_p0_x, float gradient_p1_x); diff --git a/include/stb_textedit.h b/include/stb_textedit.h index 7324fb6b..270153c1 100755 --- a/include/stb_textedit.h +++ b/include/stb_textedit.h @@ -1,4 +1,4 @@ -// [ImGui] this is a slightly modified version of stb_truetype.h 1.9. Those changes would need to be pushed into nothings/sb +// [ImGui] this is a slightly modified version of stb_textedit.h 1.9. Those changes would need to be pushed into nothings/stb // [ImGui] - fixed linestart handler when over last character of multi-line buffer + simplified existing code (#588, #815) // [ImGui] - fixed a state corruption/crash bug in stb_text_redo and stb_textedit_discard_redo (#715) // [ImGui] - fixed a crash bug in stb_textedit_discard_redo (#681) diff --git a/src/imgui/TextEditor.cpp b/src/imgui/TextEditor.cpp index 03016ffc..0a6d55ab 100755 --- a/src/imgui/TextEditor.cpp +++ b/src/imgui/TextEditor.cpp @@ -18,6 +18,18 @@ static const int cTextStart = 7; // - handle unicode/utf // - testing +template +bool equals(InputIt1 first1, InputIt1 last1, + InputIt2 first2, InputIt2 last2, BinaryPredicate p) +{ + for (; first1 != last1 && first2 != last2; ++first1, ++first2) + { + if (!p(*first1, *first2)) + return false; + } + return first1 == last1 && first2 == last2; +} + TextEditor::TextEditor() : mLineSpacing(0.0f) , mUndoIndex(0) @@ -30,6 +42,7 @@ TextEditor::TextEditor() , mTextChanged(false) , mColorRangeMin(0) , mColorRangeMax(0) + , mSelectionMode(SelectionMode::Normal) , mCheckMultilineComments(true) { SetPalette(GetDarkPalette()); @@ -555,31 +568,65 @@ void TextEditor::Render(const char* aTitle, const ImVec2& aSize, bool aBorder) if (ImGui::IsWindowHovered()) { + static float lastClick = -1.0f; if (!shift && !alt) { - if (ImGui::IsMouseClicked(0)) + auto click = ImGui::IsMouseClicked(0); + auto doubleClick = ImGui::IsMouseDoubleClicked(0); + auto t = ImGui::GetTime(); + auto tripleClick = click && !doubleClick && t - lastClick < io.MouseDoubleClickTime; + if (tripleClick) { - mState.mCursorPosition = mInteractiveStart = mInteractiveEnd = SanitizeCoordinates(ScreenPosToCoordinates(ImGui::GetMousePos())); - if (ctrl) - mWordSelectionMode = true; - SetSelection(mInteractiveStart, mInteractiveEnd, mWordSelectionMode); + printf("triple\n"); + if (!ctrl) + { + mState.mCursorPosition = mInteractiveStart = mInteractiveEnd = SanitizeCoordinates(ScreenPosToCoordinates(ImGui::GetMousePos())); + mSelectionMode = SelectionMode::Line; + SetSelection(mInteractiveStart, mInteractiveEnd, mSelectionMode); + } + + lastClick = -1.0f; + } + else if (doubleClick) + { + printf("double\n"); + if (!ctrl) + { + mState.mCursorPosition = mInteractiveStart = mInteractiveEnd = SanitizeCoordinates(ScreenPosToCoordinates(ImGui::GetMousePos())); + if (mSelectionMode == SelectionMode::Line) + mSelectionMode = SelectionMode::Normal; + else + mSelectionMode = SelectionMode::Word; + SetSelection(mInteractiveStart, mInteractiveEnd, mSelectionMode); + } + + lastClick = ImGui::GetTime(); } - if (ImGui::IsMouseDoubleClicked(0) && !ctrl) + else if (click) { + printf("single\n"); mState.mCursorPosition = mInteractiveStart = mInteractiveEnd = SanitizeCoordinates(ScreenPosToCoordinates(ImGui::GetMousePos())); - mWordSelectionMode = true; - SetSelection(mInteractiveStart, mInteractiveEnd, mWordSelectionMode); + if (ctrl) + mSelectionMode = SelectionMode::Word; + else + mSelectionMode = SelectionMode::Normal; + SetSelection(mInteractiveStart, mInteractiveEnd, mSelectionMode); + + lastClick = ImGui::GetTime(); } else if (ImGui::IsMouseDragging(0) && ImGui::IsMouseDown(0)) { io.WantCaptureMouse = true; mState.mCursorPosition = mInteractiveEnd = SanitizeCoordinates(ScreenPosToCoordinates(ImGui::GetMousePos())); - SetSelection(mInteractiveStart, mInteractiveEnd, mWordSelectionMode); + SetSelection(mInteractiveStart, mInteractiveEnd, mSelectionMode); + } + else + { } } - if (!ImGui::IsMouseDown(0)) - mWordSelectionMode = false; + //if (!ImGui::IsMouseDown(0)) + // mWordSelectionMode = false; } ColorizeInternal(); @@ -866,18 +913,34 @@ void TextEditor::SetSelectionEnd(const Coordinates & aPosition) std::swap(mState.mSelectionStart, mState.mSelectionEnd); } -void TextEditor::SetSelection(const Coordinates & aStart, const Coordinates & aEnd, bool aWordMode) +void TextEditor::SetSelection(const Coordinates & aStart, const Coordinates & aEnd, SelectionMode aMode) { mState.mSelectionStart = SanitizeCoordinates(aStart); mState.mSelectionEnd = SanitizeCoordinates(aEnd); if (aStart > aEnd) std::swap(mState.mSelectionStart, mState.mSelectionEnd); - if (aWordMode) + switch (aMode) + { + case TextEditor::SelectionMode::Normal: + break; + case TextEditor::SelectionMode::Word: { mState.mSelectionStart = FindWordStart(mState.mSelectionStart); if (!IsOnWordBoundary(mState.mSelectionEnd)) mState.mSelectionEnd = FindWordEnd(FindWordStart(mState.mSelectionEnd)); + break; + } + case TextEditor::SelectionMode::Line: + { + const auto lineNo = mState.mSelectionEnd.mLine; + const auto lineSize = lineNo < mLines.size() ? mLines[lineNo].size() : 0; + mState.mSelectionStart = Coordinates(mState.mSelectionStart.mLine, 0); + mState.mSelectionEnd = Coordinates(lineNo, (int) lineSize); + break; + } + default: + break; } } @@ -1011,7 +1074,7 @@ void TextEditor::MoveLeft(int aAmount, bool aSelect, bool aWordMode) } else mInteractiveStart = mInteractiveEnd = mState.mCursorPosition; - SetSelection(mInteractiveStart, mInteractiveEnd, aSelect && aWordMode); + SetSelection(mInteractiveStart, mInteractiveEnd, aSelect && aWordMode ? SelectionMode::Word : SelectionMode::Normal); EnsureCursorVisible(); } @@ -1056,7 +1119,7 @@ void TextEditor::MoveRight(int aAmount, bool aSelect, bool aWordMode) } else mInteractiveStart = mInteractiveEnd = mState.mCursorPosition; - SetSelection(mInteractiveStart, mInteractiveEnd, aSelect && aWordMode); + SetSelection(mInteractiveStart, mInteractiveEnd, aSelect && aWordMode ? SelectionMode::Word : SelectionMode::Normal); EnsureCursorVisible(); } @@ -1603,7 +1666,7 @@ void TextEditor::ColorizeInternal() auto from = line.begin() + i.mColumn; auto& startStr = mLanguageDefinition.mCommentStart; if (i.mColumn + startStr.size() <= line.size() && - std::equal(startStr.begin(), startStr.end(), from, from + startStr.size(), pred)) + equals(startStr.begin(), startStr.end(), from, from + startStr.size(), pred)) commentStart = i; inComment = commentStart <= i; @@ -1612,7 +1675,7 @@ void TextEditor::ColorizeInternal() auto& endStr = mLanguageDefinition.mCommentEnd; if (i.mColumn + 1 >= (int)endStr.size() && - std::equal(endStr.begin(), endStr.end(), from + 1 - endStr.size(), from + 1, pred)) + equals(endStr.begin(), endStr.end(), from + 1 - endStr.size(), from + 1, pred)) commentStart = end; } } @@ -1775,7 +1838,7 @@ TextEditor::LanguageDefinition TextEditor::LanguageDefinition::CPlusPlus() } langDef.mTokenRegexStrings.push_back(std::make_pair("//.*", PaletteIndex::Comment)); - langDef.mTokenRegexStrings.push_back(std::make_pair("[ \t]*#[ \\t]*[a-zA-Z_]+", PaletteIndex::Preprocessor)); + langDef.mTokenRegexStrings.push_back(std::make_pair("[ \\t]*#[ \\t]*[a-zA-Z_]+", PaletteIndex::Preprocessor)); langDef.mTokenRegexStrings.push_back(std::make_pair("L?\\\"(\\\\.|[^\\\"])*\\\"", PaletteIndex::String)); langDef.mTokenRegexStrings.push_back(std::make_pair("\\'\\\\?[^\\']\\'", PaletteIndex::CharLiteral)); langDef.mTokenRegexStrings.push_back(std::make_pair("0[xX][0-9a-fA-F]+[uU]?[lL]?[lL]?", PaletteIndex::Number)); @@ -1846,7 +1909,7 @@ TextEditor::LanguageDefinition TextEditor::LanguageDefinition::HLSL() } langDef.mTokenRegexStrings.push_back(std::make_pair("//.*", PaletteIndex::Comment)); - langDef.mTokenRegexStrings.push_back(std::make_pair("[ \t]*#[ \\t]*[a-zA-Z_]+", PaletteIndex::Preprocessor)); + langDef.mTokenRegexStrings.push_back(std::make_pair("[ \\t]*#[ \\t]*[a-zA-Z_]+", PaletteIndex::Preprocessor)); langDef.mTokenRegexStrings.push_back(std::make_pair("L?\\\"(\\\\.|[^\\\"])*\\\"", PaletteIndex::String)); langDef.mTokenRegexStrings.push_back(std::make_pair("\\'\\\\?[^\\']\\'", PaletteIndex::CharLiteral)); langDef.mTokenRegexStrings.push_back(std::make_pair("[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?", PaletteIndex::Number)); @@ -1909,7 +1972,7 @@ TextEditor::LanguageDefinition TextEditor::LanguageDefinition::GLSL() } langDef.mTokenRegexStrings.push_back(std::make_pair("//.*", PaletteIndex::Comment)); - langDef.mTokenRegexStrings.push_back(std::make_pair("[ \t]*#[ \\t]*[a-zA-Z_]+", PaletteIndex::Preprocessor)); + langDef.mTokenRegexStrings.push_back(std::make_pair("[ \\t]*#[ \\t]*[a-zA-Z_]+", PaletteIndex::Preprocessor)); langDef.mTokenRegexStrings.push_back(std::make_pair("L?\\\"(\\\\.|[^\\\"])*\\\"", PaletteIndex::String)); langDef.mTokenRegexStrings.push_back(std::make_pair("\\'\\\\?[^\\']\\'", PaletteIndex::CharLiteral)); langDef.mTokenRegexStrings.push_back(std::make_pair("[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?", PaletteIndex::Number)); @@ -1957,7 +2020,7 @@ TextEditor::LanguageDefinition TextEditor::LanguageDefinition::C() } langDef.mTokenRegexStrings.push_back(std::make_pair("//.*", PaletteIndex::Comment)); - langDef.mTokenRegexStrings.push_back(std::make_pair("[ \t]*#[ \\t]*[a-zA-Z_]+", PaletteIndex::Preprocessor)); + langDef.mTokenRegexStrings.push_back(std::make_pair("[ \\t]*#[ \\t]*[a-zA-Z_]+", PaletteIndex::Preprocessor)); langDef.mTokenRegexStrings.push_back(std::make_pair("L?\\\"(\\\\.|[^\\\"])*\\\"", PaletteIndex::String)); langDef.mTokenRegexStrings.push_back(std::make_pair("\\'\\\\?[^\\']\\'", PaletteIndex::CharLiteral)); langDef.mTokenRegexStrings.push_back(std::make_pair("[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)([eE][+-]?[0-9]+)?[fF]?", PaletteIndex::Number)); diff --git a/src/imgui/imgui.cpp b/src/imgui/imgui.cpp index 33b35193..0e573294 100755 --- a/src/imgui/imgui.cpp +++ b/src/imgui/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.60 +// dear imgui, v1.61 // (main code and documentation) // Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp for demo code. @@ -124,7 +124,7 @@ - Call ImGui::NewFrame() to begin the frame - You can use any ImGui function you want between NewFrame() and Render() - Call ImGui::Render() as late as you can to end the frame and finalize render data. it will call your io.RenderDrawListFn handler. - (Even if you don't render, call Render() and ignore the callback, or call EndFrame() instead. Otherwhise some features will break) + (Even if you don't render, call Render() and ignore the callback, or call EndFrame() instead. Otherwise some features will break) - All rendering information are stored into command-lists until ImGui::Render() is called. - Dear ImGui never touches or knows about your GPU state. the only function that knows about GPU is the RenderDrawListFn handler that you provide. - Effectively it means you can create widgets at any time in your code, regardless of considerations of being in "update" vs "render" phases @@ -142,7 +142,7 @@ // Load texture atlas (there is a default font so you don't need to care about choosing a font yet) unsigned char* pixels; int width, height; - io.Fonts->GetTexDataAsRGBA32(pixels, &width, &height); + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // TODO: At this points you've got the texture data and you need to upload that your your graphic system: MyTexture* texture = MyEngine::CreateTextureFromMemoryPixels(pixels, width, height, TEXTURE_TYPE_RGBA) // TODO: Store your texture pointer/identifier (whatever your engine uses) in 'io.Fonts->TexID'. This will be passed back to your via the renderer. @@ -216,7 +216,7 @@ - The examples/ folders contains many functional implementation of the pseudo-code above. - When calling NewFrame(), the 'io.WantCaptureMouse', 'io.WantCaptureKeyboard' and 'io.WantTextInput' flags are updated. They tell you if ImGui intends to use your inputs. When a flag is set you want to hide the corresponding inputs from the rest of your application. - However, in both cases you need to pass on the inputs to imgui. Read the FAQ below for more information about those flags. + In both cases you need to pass on the inputs to imgui. Read the FAQ below for more information about those flags. - Please read the FAQ above. Amusingly, it is called a FAQ because people frequently have the same issues! USING GAMEPAD/KEYBOARD NAVIGATION CONTROLS [BETA] @@ -236,7 +236,7 @@ to toggle the target. Please reach out if you think the game vs navigation input sharing could be improved. - Keyboard: - Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. - NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays. + NewFrame() will automatically fill io.NavInputs[] based on your io.KeysDown[] + io.KeyMap[] arrays. - When keyboard navigation is active (io.NavActive + ImGuiConfigFlags_NavEnableKeyboard), the io.WantCaptureKeyboard flag will be set. For more advanced uses, you may want to read from: - io.NavActive: true when a window is focused and it doesn't have the ImGuiWindowFlags_NoNavInputs flag set. @@ -258,20 +258,28 @@ API BREAKING CHANGES ==================== - Occasionally introducing changes that are breaking the API. The breakage are generally minor and easy to fix. - Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. - Also read releases logs https://github.com/ocornut/imgui/releases for more details. - - - 2018/03/20 (1.60) - Renamed io.WantMoveMouse to io.WantSetMousePos for consistency and ease of understanding (was added in 1.52, _not_ used by core and only honored by some binding ahead of merging the Nav branch). - - 2018/03/12 (1.60) - Removed ImGuiCol_CloseButton, ImGuiCol_CloseButtonActive, ImGuiCol_CloseButtonHovered as the closing cross uses regular button colors now. - - 2018/03/08 (1.60) - Changed ImFont::DisplayOffset.y to default to 0 instead of +1. Fixed rounding of Ascent/Descent to match TrueType renderer. If you were adding or subtracting to ImFont::DisplayOffset check if your fonts are correctly aligned vertically. - - 2018/03/03 (1.60) - Renamed ImGuiStyleVar_Count_ to ImGuiStyleVar_COUNT and ImGuiMouseCursor_Count_ to ImGuiMouseCursor_COUNT for consistency with other public enums. + Occasionally introducing changes that are breaking the API. We try to make the breakage minor and easy to fix. + Below is a change-log of API breaking changes only. If you are using one of the functions listed, expect to have to fix some code. + When you are not sure about a old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. + You can read releases logs https://github.com/ocornut/imgui/releases for more details. + + - 2018/05/03 (1.61) - DragInt(): The default compile-time format string has been changed from "%.0f" to "%d", as we are not using integers internally any more. + If you used DragInt() with custom format strings, make sure you change them to use %d or an integer-compatible format. + To honor backward-compatibility, the DragInt() code will currently parse and modify format strings to replace %*f with %d, giving time to users to upgrade their code. + If you have IMGUI_DISABLE_OBSOLETE_FUNCTIONS enabled, the code will instead assert! You may run a reg-exp search on your codebase for e.g. "DragInt.*%f" to help you find them. + - 2018/04/28 (1.61) - obsoleted InputFloat() functions taking an optional "int decimal_precision" in favor of an equivalent and more flexible "const char* format", + consistent with other functions. Kept redirection functions (will obsolete). + - 2018/04/09 (1.61) - IM_DELETE() helper function added in 1.60 doesn't clear the input _pointer_ reference, more consistent with expectation and allows passing r-value. + - 2018/03/20 (1.60) - renamed io.WantMoveMouse to io.WantSetMousePos for consistency and ease of understanding (was added in 1.52, _not_ used by core and only honored by some binding ahead of merging the Nav branch). + - 2018/03/12 (1.60) - removed ImGuiCol_CloseButton, ImGuiCol_CloseButtonActive, ImGuiCol_CloseButtonHovered as the closing cross uses regular button colors now. + - 2018/03/08 (1.60) - changed ImFont::DisplayOffset.y to default to 0 instead of +1. Fixed rounding of Ascent/Descent to match TrueType renderer. If you were adding or subtracting to ImFont::DisplayOffset check if your fonts are correctly aligned vertically. + - 2018/03/03 (1.60) - renamed ImGuiStyleVar_Count_ to ImGuiStyleVar_COUNT and ImGuiMouseCursor_Count_ to ImGuiMouseCursor_COUNT for consistency with other public enums. - 2018/02/18 (1.60) - BeginDragDropSource(): temporarily removed the optional mouse_button=0 parameter because it is not really usable in many situations at the moment. - 2018/02/16 (1.60) - obsoleted the io.RenderDrawListsFn callback, you can call your graphics engine render function after ImGui::Render(). Use ImGui::GetDrawData() to retrieve the ImDrawData* to display. - 2018/02/07 (1.60) - reorganized context handling to be more explicit, - YOU NOW NEED TO CALL ImGui::CreateContext() AT THE BEGINNING OF YOUR APP, AND CALL ImGui::DestroyContext() AT THE END. - removed Shutdown() function, as DestroyContext() serve this purpose. - - you may pass a ImFontAtlas* pointer to CreateContext() to share a font atlas between contexts. Otherwhise CreateContext() will create its own font atlas instance. + - you may pass a ImFontAtlas* pointer to CreateContext() to share a font atlas between contexts. Otherwise CreateContext() will create its own font atlas instance. - removed allocator parameters from CreateContext(), they are now setup with SetAllocatorFunctions(), and shared by all contexts. - removed the default global context and font atlas instance, which were confusing for users of DLL reloading and users of multiple contexts. - 2018/01/31 (1.60) - moved sample TTF files from extra_fonts/ to misc/fonts/. If you loaded files directly from the imgui repo you may need to update your paths. @@ -325,7 +333,7 @@ - 2016/07/30 (1.50) - SameLine(x) with x>0.0f is now relative to left of column/group if any, and not always to left of window. This was sort of always the intent and hopefully breakage should be minimal. - 2016/05/12 (1.49) - title bar (using ImGuiCol_TitleBg/ImGuiCol_TitleBgActive colors) isn't rendered over a window background (ImGuiCol_WindowBg color) anymore. If your TitleBg/TitleBgActive alpha was 1.0f or you are using the default theme it will not affect you. - However if your TitleBg/TitleBgActive alpha was <1.0f you need to tweak your custom theme to readjust for the fact that we don't draw a WindowBg background behind the title bar. + If your TitleBg/TitleBgActive alpha was <1.0f you need to tweak your custom theme to readjust for the fact that we don't draw a WindowBg background behind the title bar. This helper function will convert an old TitleBg/TitleBgActive color into a new one with the same visual output, given the OLD color and the OLD WindowBg color. ImVec4 ConvertTitleBgCol(const ImVec4& win_bg_col, const ImVec4& title_bg_col) { @@ -432,7 +440,7 @@ perfectly fine, as the bool toggle fairly rarely. If you have on a touch device, you might find use for an early call to NewFrameUpdateHoveredWindowAndCaptureFlags(). Note: Text input widget releases focus on "Return KeyDown", so the subsequent "Return KeyUp" event that your application receive will typically have 'io.WantCaptureKeyboard=false'. Depending on your application logic it may or not be inconvenient. You might want to track which key-downs - were targetted for Dear ImGui, e.g. with an array of bool, and filter out the corresponding key-ups.) + were targeted for Dear ImGui, e.g. with an array of bool, and filter out the corresponding key-ups.) Q: How can I display an image? What is ImTextureID, how does it works? A: ImTextureID is a void* used to pass renderer-agnostic texture references around until it hits your render function. @@ -661,7 +669,6 @@ #include "imgui_internal.h" #include // toupper, isprint -#include // NULL, malloc, free, qsort, atoi #include // vsnprintf, sscanf, printf #if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier #include // intptr_t @@ -707,6 +714,15 @@ #define IMGUI_CDECL #endif +static const ImS32 IM_S32_MIN = 0x80000000; // INT_MIN; +static const ImS32 IM_S32_MAX = 0x7FFFFFFF; // INT_MAX; +static const ImU32 IM_U32_MIN = 0; +static const ImU32 IM_U32_MAX = 0xFFFFFFFF; +static const ImS64 IM_S64_MIN = -9223372036854775807ll - 1ll; +static const ImS64 IM_S64_MAX = 9223372036854775807ll; +static const ImU64 IM_U64_MIN = 0; +static const ImU64 IM_U64_MAX = 0xFFFFFFFFFFFFFFFFull; + //------------------------------------------------------------------------- // Forward Declarations //------------------------------------------------------------------------- @@ -723,7 +739,7 @@ static void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, static ImGuiWindow* FindHoveredWindow(); static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags); static void CheckStacksSize(ImGuiWindow* window, bool write); -static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window); +static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool snap_on_edges); static void AddDrawListToDrawData(ImVector* out_list, ImDrawList* draw_list); static void AddWindowToDrawData(ImVector* out_list, ImGuiWindow* window); @@ -731,25 +747,17 @@ static void AddWindowToSortedBuffer(ImVector* out_sort static ImGuiWindowSettings* AddWindowSettings(const char* name); -static void LoadIniSettingsFromDisk(const char* ini_filename); -static void LoadIniSettingsFromMemory(const char* buf); -static void SaveIniSettingsToDisk(const char* ini_filename); -static void SaveIniSettingsToMemory(ImVector& out_buf); -static void MarkIniSettingsDirty(ImGuiWindow* window); - static ImRect GetViewportRect(); static void ClosePopupToLevel(int remaining); -static ImGuiWindow* GetFrontMostModalRootWindow(); static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data); static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end); static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL, ImVec2* out_offset = NULL, bool stop_on_new_line = false); -static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, const char* display_format, char* buf, int buf_size); -static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, int decimal_precision, char* buf, int buf_size); +static inline int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* data_ptr, const char* format); static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, void* arg_1, const void* arg_2); -static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* scalar_format); +static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* format); namespace ImGui { @@ -757,10 +765,17 @@ static void NavUpdate(); static void NavUpdateWindowing(); static void NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, const ImGuiID id); -static void NewFrameUpdateMovingWindow(); -static void NewFrameUpdateMouseInputs(); +static void UpdateMovingWindow(); +static void UpdateMouseInputs(); static void UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]); static void FocusFrontMostActiveWindow(ImGuiWindow* ignore_window); + +// Template widget behaviors +template +static bool DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const TYPE v_min, const TYPE v_max, const char* format, float power); + +template +static bool SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, TYPE* v, const TYPE v_min, const TYPE v_max, const char* format, float power, ImGuiSliderFlags flags); } //----------------------------------------------------------------------------- @@ -775,7 +790,7 @@ static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y); // Context //----------------------------------------------------------------------------- -// Current context pointer. Implicitely used by all ImGui functions. Always assumed to be != NULL. +// Current context pointer. Implicitly used by all ImGui functions. Always assumed to be != NULL. // CreateContext() will automatically set this pointer if it is NULL. Change to a different context by calling ImGui::SetCurrentContext(). // If you use DLL hotreloading you might need to call SetCurrentContext() after reloading code from this file. // ImGui functions are not thread-safe because of this pointer. If you want thread-safety to allow N threads to access N different contexts, you can: @@ -830,8 +845,8 @@ ImGuiStyle::ImGuiStyle() GrabMinSize = 10.0f; // Minimum width/height of a grab box for slider/scrollbar GrabRounding = 0.0f; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. ButtonTextAlign = ImVec2(0.5f,0.5f);// Alignment of button text when button is larger than text. - DisplayWindowPadding = ImVec2(22,22); // Window positions are clamped to be visible within the display area by at least this amount. Only covers regular windows. - DisplaySafeAreaPadding = ImVec2(4,4); // 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. + DisplayWindowPadding = ImVec2(20,20); // Window positions are clamped to be visible within the display area by at least this amount. Only covers 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. AntiAliasedLines = true; // Enable anti-aliasing on lines/borders. Disable if you are really short on CPU/GPU. AntiAliasedFill = true; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) @@ -949,6 +964,7 @@ void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars) // HELPERS //----------------------------------------------------------------------------- +#define IM_STATIC_ASSERT(_COND) typedef char static_assertion_##__line__[(_COND)?1:-1] #define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose #define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255 @@ -1072,12 +1088,29 @@ const char* ImStristr(const char* haystack, const char* haystack_end, const char return NULL; } -static const char* ImAtoi(const char* src, int* output) +// Trim str by offsetting contents when there's leading data + writing a \0 at the trailing position. We use this in situation where the cost is negligible. +void ImStrTrimBlanks(char* buf) +{ + char* p = buf; + while (p[0] == ' ' || p[0] == '\t') // Leading blanks + p++; + char* p_start = p; + while (*p != 0) // Find end of string + p++; + while (p > p_start && (p[-1] == ' ' || p[-1] == '\t')) // Trailing blanks + p--; + if (p_start != buf) // Copy memory if we had leading blanks + memmove(buf, p_start, p - p_start); + buf[p - p_start] = 0; // Zero terminate +} + +template +static const char* ImAtoi(const char* src, TYPE* output) { int negative = 0; if (*src == '-') { negative = 1; src++; } if (*src == '+') { src++; } - int v = 0; + TYPE v = 0; while (*src >= '0' && *src <= '9') v = (v * 10) + (*src++ - '0'); *output = negative ? -v : v; @@ -1403,7 +1436,7 @@ void ImGui::ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& } const float chroma = r - (g < b ? g : b); - out_h = fabsf(K + (g - b) / (6.f * chroma + 1e-20f)); + out_h = ImFabs(K + (g - b) / (6.f * chroma + 1e-20f)); out_s = chroma / (r + 1e-20f); out_v = r; } @@ -1419,7 +1452,7 @@ void ImGui::ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& return; } - h = fmodf(h, 1.0f) / (60.0f/360.0f); + h = ImFmod(h, 1.0f) / (60.0f/360.0f); int i = (int)h; float f = h - (float)i; float p = v * (1.0f - s); @@ -1455,7 +1488,7 @@ FILE* ImFileOpen(const char* filename, const char* mode) // Load file content into memory // Memory allocated with ImGui::MemAlloc(), must be freed by user using ImGui::MemFree() -void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, int* out_file_size, int padding_bytes) +void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, size_t* out_file_size, int padding_bytes) { IM_ASSERT(filename && file_open_mode); if (out_file_size) @@ -1472,14 +1505,14 @@ void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, int* return NULL; } - int file_size = (int)file_size_signed; - void* file_data = ImGui::MemAlloc((size_t)(file_size + padding_bytes)); + size_t file_size = (size_t)file_size_signed; + void* file_data = ImGui::MemAlloc(file_size + padding_bytes); if (file_data == NULL) { fclose(f); return NULL; } - if (fread(file_data, 1, (size_t)file_size, f) != (size_t)file_size) + if (fread(file_data, 1, file_size, f) != file_size) { fclose(f); ImGui::MemFree(file_data); @@ -1762,7 +1795,10 @@ void ImGuiTextBuffer::appendfv(const char* fmt, va_list args) int len = ImFormatStringV(NULL, 0, fmt, args); // FIXME-OPT: could do a first pass write attempt, likely successful on first pass. if (len <= 0) + { + va_end(args_copy); return; + } const int write_off = Buf.Size; const int needed_sz = write_off + len; @@ -1774,6 +1810,7 @@ void ImGuiTextBuffer::appendfv(const char* fmt, va_list args) Buf.resize(needed_sz); ImFormatStringV(&Buf[write_off - 1], (size_t)len + 1, fmt, args_copy); + va_end(args_copy); } void ImGuiTextBuffer::appendf(const char* fmt, ...) @@ -1918,12 +1955,13 @@ bool ImGuiListClipper::Step() //----------------------------------------------------------------------------- ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) + : DrawListInst(&context->DrawListSharedData) { Name = ImStrdup(name); ID = ImHash(name, 0); IDStack.push_back(ID); Flags = 0; - PosFloat = Pos = ImVec2(0.0f, 0.0f); + Pos = ImVec2(0.0f, 0.0f); Size = SizeFull = ImVec2(0.0f, 0.0f); SizeContents = SizeContentsExplicit = ImVec2(0.0f, 0.0f); WindowPadding = ImVec2(0.0f, 0.0f); @@ -1934,8 +1972,8 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) Scroll = ImVec2(0.0f, 0.0f); ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); ScrollTargetCenterRatio = ImVec2(0.5f, 0.5f); - ScrollbarX = ScrollbarY = false; ScrollbarSizes = ImVec2(0.0f, 0.0f); + ScrollbarX = ScrollbarY = false; Active = WasActive = false; WriteAccessed = false; Collapsed = false; @@ -1959,7 +1997,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) ItemWidthDefault = 0.0f; FontWindowScale = 1.0f; - DrawList = IM_NEW(ImDrawList)(&context->DrawListSharedData); + DrawList = &DrawListInst; DrawList->_OwnerName = Name; ParentWindow = NULL; RootWindow = NULL; @@ -1978,7 +2016,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) ImGuiWindow::~ImGuiWindow() { - IM_DELETE(DrawList); + IM_ASSERT(DrawList == &DrawListInst); IM_DELETE(Name); for (int i = 0; i != ColumnsStorage.Size; i++) ColumnsStorage[i].~ImGuiColumnsSet(); @@ -2170,14 +2208,14 @@ void ImGui::ItemSize(const ImRect& bb, float text_offset_y) ItemSize(bb.GetSize(), text_offset_y); } -static ImGuiDir NavScoreItemGetQuadrant(float dx, float dy) +static ImGuiDir inline NavScoreItemGetQuadrant(float dx, float dy) { - if (fabsf(dx) > fabsf(dy)) + if (ImFabs(dx) > ImFabs(dy)) return (dx > 0.0f) ? ImGuiDir_Right : ImGuiDir_Left; return (dy > 0.0f) ? ImGuiDir_Down : ImGuiDir_Up; } -static float NavScoreItemDistInterval(float a0, float a1, float b0, float b1) +static float inline NavScoreItemDistInterval(float a0, float a1, float b0, float b1) { if (a1 < b0) return a1 - b0; @@ -2186,6 +2224,20 @@ static float NavScoreItemDistInterval(float a0, float a1, float b0, float b1) return 0.0f; } +static void inline NavClampRectToVisibleAreaForMoveDir(ImGuiDir move_dir, ImRect& r, const ImRect& clip_rect) +{ + if (move_dir == ImGuiDir_Left || move_dir == ImGuiDir_Right) + { + r.Min.y = ImClamp(r.Min.y, clip_rect.Min.y, clip_rect.Max.y); + r.Max.y = ImClamp(r.Max.y, clip_rect.Min.y, clip_rect.Max.y); + } + else + { + r.Min.x = ImClamp(r.Min.x, clip_rect.Min.x, clip_rect.Max.x); + r.Max.x = ImClamp(r.Max.x, clip_rect.Min.x, clip_rect.Max.x); + } +} + // Scoring function for directional navigation. Based on https://gist.github.com/rygorous/6981057 static bool NavScoreItem(ImGuiNavMoveResult* result, ImRect cand) { @@ -2197,17 +2249,9 @@ static bool NavScoreItem(ImGuiNavMoveResult* result, ImRect cand) const ImRect& curr = g.NavScoringRectScreen; // Current modified source rect (NB: we've applied Max.x = Min.x in NavUpdate() to inhibit the effect of having varied item width) g.NavScoringCount++; - // We perform scoring on items bounding box clipped by their parent window on the other axis (clipping on our movement axis would give us equal scores for all clipped items) - if (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right) - { - cand.Min.y = ImClamp(cand.Min.y, window->ClipRect.Min.y, window->ClipRect.Max.y); - cand.Max.y = ImClamp(cand.Max.y, window->ClipRect.Min.y, window->ClipRect.Max.y); - } - else - { - cand.Min.x = ImClamp(cand.Min.x, window->ClipRect.Min.x, window->ClipRect.Max.x); - cand.Max.x = ImClamp(cand.Max.x, window->ClipRect.Min.x, window->ClipRect.Max.x); - } + // We perform scoring on items bounding box clipped by the current clipping rectangle on the other axis (clipping on our movement axis would give us equal scores for all clipped items) + // For example, this ensure that items in one column are not reached when moving vertically from items in another column. + NavClampRectToVisibleAreaForMoveDir(g.NavMoveDir, cand, window->ClipRect); // Compute distance between boxes // FIXME-NAV: Introducing biases for vertical navigation, needs to be removed. @@ -2215,12 +2259,12 @@ static bool NavScoreItem(ImGuiNavMoveResult* result, ImRect cand) float dby = NavScoreItemDistInterval(ImLerp(cand.Min.y, cand.Max.y, 0.2f), ImLerp(cand.Min.y, cand.Max.y, 0.8f), ImLerp(curr.Min.y, curr.Max.y, 0.2f), ImLerp(curr.Min.y, curr.Max.y, 0.8f)); // Scale down on Y to keep using box-distance for vertically touching items if (dby != 0.0f && dbx != 0.0f) dbx = (dbx/1000.0f) + ((dbx > 0.0f) ? +1.0f : -1.0f); - float dist_box = fabsf(dbx) + fabsf(dby); + float dist_box = ImFabs(dbx) + ImFabs(dby); // Compute distance between centers (this is off by a factor of 2, but we only compare center distances with each other so it doesn't matter) float dcx = (cand.Min.x + cand.Max.x) - (curr.Min.x + curr.Max.x); float dcy = (cand.Min.y + cand.Max.y) - (curr.Min.y + curr.Max.y); - float dist_center = fabsf(dcx) + fabsf(dcy); // L1 metric (need this for our connectedness guarantee) + float dist_center = ImFabs(dcx) + ImFabs(dcy); // L1 metric (need this for our connectedness guarantee) // Determine which quadrant of 'curr' our candidate item 'cand' lies in based on distance ImGuiDir quadrant; @@ -2252,10 +2296,11 @@ static bool NavScoreItem(ImGuiNavMoveResult* result, ImRect cand) if (ImGui::IsMouseHoveringRect(cand.Min, cand.Max)) { ImFormatString(buf, IM_ARRAYSIZE(buf), "dbox (%.2f,%.2f->%.4f)\ndcen (%.2f,%.2f->%.4f)\nd (%.2f,%.2f->%.4f)\nnav %c, quadrant %c", dbx, dby, dist_box, dcx, dcy, dist_center, dax, day, dist_axial, "WENS"[g.NavMoveDir], "WENS"[quadrant]); - g.OverlayDrawList.AddRect(curr.Min, curr.Max, IM_COL32(255, 200, 0, 100)); - g.OverlayDrawList.AddRect(cand.Min, cand.Max, IM_COL32(255,255,0,200)); - g.OverlayDrawList.AddRectFilled(cand.Max-ImVec2(4,4), cand.Max+ImGui::CalcTextSize(buf)+ImVec2(4,4), IM_COL32(40,0,0,150)); - g.OverlayDrawList.AddText(g.IO.FontDefault, 13.0f, cand.Max, ~0U, buf); + ImDrawList* draw_list = ImGui::GetOverlayDrawList(); + draw_list->AddRect(curr.Min, curr.Max, IM_COL32(255,200,0,100)); + draw_list->AddRect(cand.Min, cand.Max, IM_COL32(255,255,0,200)); + draw_list->AddRectFilled(cand.Max-ImVec2(4,4), cand.Max+ImGui::CalcTextSize(buf)+ImVec2(4,4), IM_COL32(40,0,0,150)); + draw_list->AddText(g.IO.FontDefault, 13.0f, cand.Max, ~0U, buf); } else if (g.IO.KeyCtrl) // Hold to preview score in matching quadrant. Press C to rotate. { @@ -2263,8 +2308,9 @@ static bool NavScoreItem(ImGuiNavMoveResult* result, ImRect cand) if (quadrant == g.NavMoveDir) { ImFormatString(buf, IM_ARRAYSIZE(buf), "%.0f/%.0f", dist_box, dist_center); - g.OverlayDrawList.AddRectFilled(cand.Min, cand.Max, IM_COL32(255, 0, 0, 200)); - g.OverlayDrawList.AddText(g.IO.FontDefault, 13.0f, cand.Min, IM_COL32(255, 255, 255, 255), buf); + ImDrawList* draw_list = ImGui::GetOverlayDrawList(); + draw_list->AddRectFilled(cand.Min, cand.Max, IM_COL32(255, 0, 0, 200)); + draw_list->AddText(g.IO.FontDefault, 13.0f, cand.Min, IM_COL32(255, 255, 255, 255), buf); } } #endif @@ -2303,7 +2349,7 @@ static bool NavScoreItem(ImGuiNavMoveResult* result, ImRect cand) // are found, so it only augments the graph produced by the above method using extra links. (important, since it doesn't guarantee strong connectedness) // This is just to avoid buttons having no links in a particular direction when there's a suitable neighbor. you get good graphs without this too. // 2017/09/29: FIXME: This now currently only enabled inside menu bars, ideally we'd disable it everywhere. Menus in particular need to catch failure. For general navigation it feels awkward. - // Disabling it may however lead to disconnected graphs when nodes are very spaced out on different axis. Perhaps consider offering this as an option? + // Disabling it may lead to disconnected graphs when nodes are very spaced out on different axis. Perhaps consider offering this as an option? if (result->DistBox == FLT_MAX && dist_axial < result->DistAxial) // Check axial match if (g.NavLayer == 1 && !(g.NavWindow->Flags & ImGuiWindowFlags_ChildMenu)) if ((g.NavMoveDir == ImGuiDir_Left && dax < 0.0f) || (g.NavMoveDir == ImGuiDir_Right && dax > 0.0f) || (g.NavMoveDir == ImGuiDir_Up && day < 0.0f) || (g.NavMoveDir == ImGuiDir_Down && day > 0.0f)) @@ -2388,6 +2434,7 @@ static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, con } // Scoring for navigation + // FIXME-NAV: Consider policy for double scoring (scoring from NavScoringRectScreen + scoring from a rect wrapped according to current wrapping policy) if (g.NavId != id && !(item_flags & ImGuiItemFlags_NoNav)) { ImGuiNavMoveResult* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther; @@ -2593,10 +2640,10 @@ float ImGui::CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x) //----------------------------------------------------------------------------- -void* ImGui::MemAlloc(size_t sz) +void* ImGui::MemAlloc(size_t size) { GImAllocatorActiveAllocationsCount++; - return GImAllocatorAllocFunc(sz, GImAllocatorUserData); + return GImAllocatorAllocFunc(size, GImAllocatorUserData); } void ImGui::MemFree(void* ptr) @@ -2637,6 +2684,20 @@ void ImGui::SetCurrentContext(ImGuiContext* ctx) #endif } +// Helper function to verify that the type sizes are matching between the calling file's compilation unit and imgui.cpp's compilation unit +// If the user has inconsistent compilation settings, imgui configuration #define, packing pragma, etc. you may see different structures from what imgui.cpp sees which is highly problematic. +bool ImGui::DebugCheckVersionAndDataLayout(const char* version, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_vert) +{ + bool error = false; + if (strcmp(version, IMGUI_VERSION)!=0) { error = true; IM_ASSERT(strcmp(version,IMGUI_VERSION)==0 && "Mismatch version string!"); } + if (sz_io != sizeof(ImGuiIO)) { error = true; IM_ASSERT(sz_io == sizeof(ImGuiIO) && "Mismatched struct layout!"); } + if (sz_style != sizeof(ImGuiStyle)) { error = true; IM_ASSERT(sz_style == sizeof(ImGuiStyle) && "Mismatched struct layout!"); } + if (sz_vec2 != sizeof(ImVec2)) { error = true; IM_ASSERT(sz_vec2 == sizeof(ImVec2) && "Mismatched struct layout!"); } + if (sz_vec4 != sizeof(ImVec4)) { error = true; IM_ASSERT(sz_vec4 == sizeof(ImVec4) && "Mismatched struct layout!"); } + if (sz_vert != sizeof(ImDrawVert)) { error = true; IM_ASSERT(sz_vert == sizeof(ImDrawVert) && "Mismatched struct layout!"); } + return !error; +} + void ImGui::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void(*free_func)(void* ptr, void* user_data), void* user_data) { GImAllocatorAllocFunc = alloc_func; @@ -2726,13 +2787,14 @@ void ImGui::NavInitWindow(ImGuiWindow* window, bool force_reinit) } } -static ImVec2 NavCalcPreferredMousePos() +static ImVec2 NavCalcPreferredRefPos() { ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.NavWindow; - if (!window) - return g.IO.MousePos; - const ImRect& rect_rel = window->NavRectRel[g.NavLayer]; + if (g.NavDisableHighlight || !g.NavDisableMouseHover || !g.NavWindow) + return ImFloor(g.IO.MousePos); + + // When navigation is active and mouse is disabled, decide on an arbitrary position around the bottom left of the currently navigated item + const ImRect& rect_rel = g.NavWindow->NavRectRel[g.NavLayer]; ImVec2 pos = g.NavWindow->Pos + ImVec2(rect_rel.Min.x + ImMin(g.Style.FramePadding.x*4, rect_rel.GetWidth()), rect_rel.Max.y - ImMin(g.Style.FramePadding.y, rect_rel.GetHeight())); ImRect visible_rect = GetViewportRect(); return ImFloor(ImClamp(pos, visible_rect.Min, visible_rect.Max)); // ImFloor() is important because non-integer mouse position application in back-end might be lossy and result in undesirable non-zero delta. @@ -2899,8 +2961,8 @@ static void ImGui::NavUpdateWindowing() if (move_delta.x != 0.0f || move_delta.y != 0.0f) { const float NAV_MOVE_SPEED = 800.0f; - const float move_speed = ImFloor(NAV_MOVE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y)); - g.NavWindowingTarget->PosFloat += move_delta * move_speed; + const float move_speed = ImFloor(NAV_MOVE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y)); // FIXME: Doesn't code variable framerate very well + g.NavWindowingTarget->Pos += move_delta * move_speed; g.NavDisableMouseHover = true; MarkIniSettingsDirty(g.NavWindowingTarget); } @@ -2946,7 +3008,7 @@ static void ImGui::NavUpdateWindowing() static void NavScrollToBringItemIntoView(ImGuiWindow* window, ImRect& item_rect_rel) { // Scroll to keep newly navigated item fully into view - ImRect window_rect_rel(window->InnerRect.Min - window->Pos - ImVec2(1, 1), window->InnerRect.Max - window->Pos + ImVec2(1, 1)); + ImRect window_rect_rel(window->InnerMainRect.Min - window->Pos - ImVec2(1, 1), window->InnerMainRect.Max - window->Pos + ImVec2(1, 1)); //g.OverlayDrawList.AddRect(window->Pos + window_rect_rel.Min, window->Pos + window_rect_rel.Max, IM_COL32_WHITE); // [DEBUG] if (window_rect_rel.Contains(item_rect_rel)) return; @@ -2973,8 +3035,8 @@ static void NavScrollToBringItemIntoView(ImGuiWindow* window, ImRect& item_rect_ window->ScrollTargetCenterRatio.y = 1.0f; } - // Estimate upcoming scroll so we can offset our relative mouse position so mouse position can be applied immediately (under this block) - ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window); + // Estimate upcoming scroll so we can offset our relative mouse position so mouse position can be applied immediately after in NavUpdate() + ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window, false); item_rect_rel.Translate(window->Scroll - next_scroll); } @@ -3063,10 +3125,11 @@ static void ImGui::NavUpdate() // Apply application mouse position movement, after we had a chance to process move request result. if (g.NavMousePosDirty && g.NavIdIsAlive) { - // Set mouse position given our knowledge of the nav widget position from last frame + // Set mouse position given our knowledge of the navigated item position from last frame if ((g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) && (g.IO.BackendFlags & ImGuiBackendFlags_HasSetMousePos)) { - g.IO.MousePos = g.IO.MousePosPrev = NavCalcPreferredMousePos(); + IM_ASSERT(!g.NavDisableHighlight && g.NavDisableMouseHover); + g.IO.MousePos = g.IO.MousePosPrev = NavCalcPreferredRefPos(); g.IO.WantSetMousePos = true; } g.NavMousePosDirty = false; @@ -3228,7 +3291,7 @@ static void ImGui::NavUpdate() if (g.NavMoveRequest && g.NavMoveFromClampedRefRect && g.NavLayer == 0) { ImGuiWindow* window = g.NavWindow; - ImRect window_rect_rel(window->InnerRect.Min - window->Pos - ImVec2(1,1), window->InnerRect.Max - window->Pos + ImVec2(1,1)); + ImRect window_rect_rel(window->InnerMainRect.Min - window->Pos - ImVec2(1,1), window->InnerMainRect.Max - window->Pos + ImVec2(1,1)); if (!window_rect_rel.Contains(window->NavRectRel[g.NavLayer])) { float pad = window->CalcFontSize() * 0.5f; @@ -3244,32 +3307,32 @@ static void ImGui::NavUpdate() g.NavScoringRectScreen = g.NavWindow ? ImRect(g.NavWindow->Pos + nav_rect_rel.Min, g.NavWindow->Pos + nav_rect_rel.Max) : GetViewportRect(); g.NavScoringRectScreen.Min.x = ImMin(g.NavScoringRectScreen.Min.x + 1.0f, g.NavScoringRectScreen.Max.x); g.NavScoringRectScreen.Max.x = g.NavScoringRectScreen.Min.x; - IM_ASSERT(!g.NavScoringRectScreen.IsInverted()); // Ensure if we have a finite, non-inverted bounding box here will allows us to remove extraneous fabsf() calls in NavScoreItem(). + IM_ASSERT(!g.NavScoringRectScreen.IsInverted()); // Ensure if we have a finite, non-inverted bounding box here will allows us to remove extraneous ImFabs() calls in NavScoreItem(). //g.OverlayDrawList.AddRect(g.NavScoringRectScreen.Min, g.NavScoringRectScreen.Max, IM_COL32(255,200,0,255)); // [DEBUG] g.NavScoringCount = 0; #if IMGUI_DEBUG_NAV_RECTS - if (g.NavWindow) { for (int layer = 0; layer < 2; layer++) g.OverlayDrawList.AddRect(g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Min, g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Max, IM_COL32(255,200,0,255)); } // [DEBUG] - if (g.NavWindow) { ImU32 col = (g.NavWindow->HiddenFrames == 0) ? IM_COL32(255,0,255,255) : IM_COL32(255,0,0,255); ImVec2 p = NavCalcPreferredMousePos(); char buf[32]; ImFormatString(buf, 32, "%d", g.NavLayer); g.OverlayDrawList.AddCircleFilled(p, 3.0f, col); g.OverlayDrawList.AddText(NULL, 13.0f, p + ImVec2(8,-4), col, buf); } + if (g.NavWindow) { for (int layer = 0; layer < 2; layer++) GetOverlayDrawList()->AddRect(g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Min, g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Max, IM_COL32(255,200,0,255)); } // [DEBUG] + if (g.NavWindow) { ImU32 col = (g.NavWindow->HiddenFrames == 0) ? IM_COL32(255,0,255,255) : IM_COL32(255,0,0,255); ImVec2 p = NavCalcPreferredRefPos(); char buf[32]; ImFormatString(buf, 32, "%d", g.NavLayer); g.OverlayDrawList.AddCircleFilled(p, 3.0f, col); g.OverlayDrawList.AddText(NULL, 13.0f, p + ImVec2(8,-4), col, buf); } #endif } -static void ImGui::NewFrameUpdateMovingWindow() +static void ImGui::UpdateMovingWindow() { ImGuiContext& g = *GImGui; - if (g.MovingWindow && g.MovingWindow->MoveId == g.ActiveId && g.ActiveIdSource == ImGuiInputSource_Mouse) + if (g.MovingWindow != NULL) { // We actually want to move the root window. g.MovingWindow == window we clicked on (could be a child window). - // We track it to preserve Focus and so that ActiveIdWindow == MovingWindow and ActiveId == MovingWindow->MoveId for consistency. + // We track it to preserve Focus and so that generally ActiveIdWindow == MovingWindow and ActiveId == MovingWindow->MoveId for consistency. KeepAliveID(g.ActiveId); IM_ASSERT(g.MovingWindow && g.MovingWindow->RootWindow); ImGuiWindow* moving_window = g.MovingWindow->RootWindow; - if (g.IO.MouseDown[0]) + if (g.IO.MouseDown[0] && IsMousePosValid(&g.IO.MousePos)) { ImVec2 pos = g.IO.MousePos - g.ActiveIdClickOffset; - if (moving_window->PosFloat.x != pos.x || moving_window->PosFloat.y != pos.y) + if (moving_window->Pos.x != pos.x || moving_window->Pos.y != pos.y) { MarkIniSettingsDirty(moving_window); - moving_window->PosFloat = pos; + SetWindowPos(moving_window, pos, ImGuiCond_Always); } FocusWindow(g.MovingWindow); } @@ -3288,16 +3351,15 @@ static void ImGui::NewFrameUpdateMovingWindow() if (!g.IO.MouseDown[0]) ClearActiveID(); } - g.MovingWindow = NULL; } } -static void ImGui::NewFrameUpdateMouseInputs() +static void ImGui::UpdateMouseInputs() { ImGuiContext& g = *GImGui; // If mouse just appeared or disappeared (usually denoted by -FLT_MAX component, but in reality we test for -256000.0f) we cancel out movement in MouseDelta - if (ImGui::IsMousePosValid(&g.IO.MousePos) && ImGui::IsMousePosValid(&g.IO.MousePosPrev)) + if (IsMousePosValid(&g.IO.MousePos) && IsMousePosValid(&g.IO.MousePosPrev)) g.IO.MouseDelta = g.IO.MousePos - g.IO.MousePosPrev; else g.IO.MouseDelta = ImVec2(0.0f, 0.0f); @@ -3353,7 +3415,7 @@ void ImGui::NewFrameUpdateHoveredWindowAndCaptureFlags() g.HoveredRootWindow = g.HoveredWindow ? g.HoveredWindow->RootWindow : NULL; // Modal windows prevents cursor from hovering behind them. - ImGuiWindow* modal_window = GetFrontMostModalRootWindow(); + ImGuiWindow* modal_window = GetFrontMostPopupModal(); if (modal_window) if (g.HoveredRootWindow && !IsWindowChildOf(g.HoveredRootWindow, modal_window)) g.HoveredRootWindow = g.HoveredWindow = NULL; @@ -3397,7 +3459,7 @@ void ImGui::NewFrameUpdateHoveredWindowAndCaptureFlags() g.IO.WantCaptureKeyboard = true; // Update io.WantTextInput flag, this is to allow systems without a keyboard (e.g. mobile, hand-held) to show a software keyboard if possible - g.IO.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : 0; + g.IO.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : false; } void ImGui::NewFrame() @@ -3406,7 +3468,7 @@ void ImGui::NewFrame() ImGuiContext& g = *GImGui; // Check user data - // (We pass an error message in the assert expression as a trick to get it visible to programmers who are not using a debugger, as most assert handlers display their argument) + // (We pass an error message in the assert expression to make it visible to programmers who are not using a debugger, as most assert handlers display their argument) IM_ASSERT(g.Initialized); IM_ASSERT(g.IO.DeltaTime >= 0.0f && "Need a positive DeltaTime (zero is tolerated but will cause some timing issues)"); IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f && "Invalid DisplaySize value"); @@ -3418,24 +3480,31 @@ void ImGui::NewFrame() for (int n = 0; n < ImGuiKey_COUNT; n++) IM_ASSERT(g.IO.KeyMap[n] >= -1 && g.IO.KeyMap[n] < IM_ARRAYSIZE(g.IO.KeysDown) && "io.KeyMap[] contains an out of bound value (need to be 0..512, or -1 for unmapped key)"); - // Do a simple check for required key mapping (we intentionally do NOT check all keys to not pressure user into setting up everything, but Space is required and was super recently added in 1.60 WIP) + // Perform simple check for required key mapping (we intentionally do NOT check all keys to not pressure user into setting up everything, but Space is required and was only recently added in 1.60 WIP) if (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) IM_ASSERT(g.IO.KeyMap[ImGuiKey_Space] != -1 && "ImGuiKey_Space is not mapped, required for keyboard navigation."); - // Load settings on first frame + // Load settings on first frame (if not explicitly loaded manually before) if (!g.SettingsLoaded) { IM_ASSERT(g.SettingsWindows.empty()); - LoadIniSettingsFromDisk(g.IO.IniFilename); + if (g.IO.IniFilename) + LoadIniSettingsFromDisk(g.IO.IniFilename); g.SettingsLoaded = true; } - // Save settings (with a delay so we don't spam disk too much) + // Save settings (with a delay after the last modification, so we don't spam disk too much) if (g.SettingsDirtyTimer > 0.0f) { g.SettingsDirtyTimer -= g.IO.DeltaTime; if (g.SettingsDirtyTimer <= 0.0f) - SaveIniSettingsToDisk(g.IO.IniFilename); + { + if (g.IO.IniFilename != NULL) + SaveIniSettingsToDisk(g.IO.IniFilename); + else + g.IO.WantSaveIniSettings = true; // Let user know they can call SaveIniSettingsToMemory(). user will need to clear io.WantSaveIniSettings themselves. + g.SettingsDirtyTimer = 0.0f; + } } g.Time += g.IO.DeltaTime; @@ -3492,26 +3561,26 @@ void ImGui::NewFrame() NavUpdate(); // Update mouse input state - NewFrameUpdateMouseInputs(); + UpdateMouseInputs(); // Calculate frame-rate for the user, as a purely luxurious feature g.FramerateSecPerFrameAccum += g.IO.DeltaTime - g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx]; g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx] = g.IO.DeltaTime; g.FramerateSecPerFrameIdx = (g.FramerateSecPerFrameIdx + 1) % IM_ARRAYSIZE(g.FramerateSecPerFrame); - g.IO.Framerate = 1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame)); + g.IO.Framerate = (g.FramerateSecPerFrameAccum > 0.0f) ? (1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame))) : FLT_MAX; // Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering) - NewFrameUpdateMovingWindow(); + UpdateMovingWindow(); NewFrameUpdateHoveredWindowAndCaptureFlags(); - if (GetFrontMostModalRootWindow() != NULL) + if (GetFrontMostPopupModal() != NULL) g.ModalWindowDarkeningRatio = ImMin(g.ModalWindowDarkeningRatio + g.IO.DeltaTime * 6.0f, 1.0f); else g.ModalWindowDarkeningRatio = 0.0f; g.MouseCursor = ImGuiMouseCursor_Arrow; g.WantCaptureMouseNextFrame = g.WantCaptureKeyboardNextFrame = g.WantTextInputNextFrame = -1; - g.OsImePosRequest = ImVec2(1.0f, 1.0f); // OS Input Method Editor showing on top-left of our window by default + g.PlatformImePos = ImVec2(1.0f, 1.0f); // OS Input Method Editor showing on top-left of our window by default // Mouse wheel scrolling, scale if (g.HoveredWindow && !g.HoveredWindow->Collapsed && (g.IO.MouseWheel != 0.0f || g.IO.MouseWheelH != 0.0f)) @@ -3534,7 +3603,6 @@ void ImGui::NewFrame() const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size; window->Pos += offset; - window->PosFloat += offset; window->Size *= scale; window->SizeFull *= scale; } @@ -3648,7 +3716,6 @@ void ImGui::Initialize(ImGuiContext* context) { ImGuiContext& g = *context; IM_ASSERT(!g.Initialized && !g.SettingsLoaded); - g.LogClipboard = IM_NEW(ImGuiTextBuffer)(); // Add .ini handle for ImGuiWindow type ImGuiSettingsHandler ini_handler; @@ -3665,17 +3732,19 @@ void ImGui::Initialize(ImGuiContext* context) // This function is merely here to free heap allocations. void ImGui::Shutdown(ImGuiContext* context) { - ImGuiContext& g = *context; - // The fonts atlas can be used prior to calling NewFrame(), so we clear it even if g.Initialized is FALSE (which would happen if we never called NewFrame) + ImGuiContext& g = *context; if (g.IO.Fonts && g.FontAtlasOwnedByContext) IM_DELETE(g.IO.Fonts); + g.IO.Fonts = NULL; - // Cleanup of other data are conditional on actually having initialize ImGui. + // Cleanup of other data are conditional on actually having initialized ImGui. if (!g.Initialized) return; - SaveIniSettingsToDisk(g.IO.IniFilename); + // Save settings (unless we haven't attempted to load them: CreateContext/DestroyContext without a call to NewFrame shouldn't save an empty file) + if (g.SettingsLoaded && g.IO.IniFilename != NULL) + SaveIniSettingsToDisk(g.IO.IniFilename); // Clear everything else for (int i = 0; i < g.Windows.Size; i++) @@ -3690,8 +3759,6 @@ void ImGui::Shutdown(ImGuiContext* context) g.HoveredRootWindow = NULL; g.ActiveIdWindow = NULL; g.MovingWindow = NULL; - for (int i = 0; i < g.SettingsWindows.Size; i++) - IM_DELETE(g.SettingsWindows[i].Name); g.ColorModifiers.clear(); g.StyleModifiers.clear(); g.FontStack.clear(); @@ -3704,6 +3771,8 @@ void ImGui::Shutdown(ImGuiContext* context) g.InputTextState.InitialText.clear(); g.InputTextState.TempTextBuffer.clear(); + for (int i = 0; i < g.SettingsWindows.Size; i++) + IM_DELETE(g.SettingsWindows[i].Name); g.SettingsWindows.clear(); g.SettingsHandlers.clear(); @@ -3712,8 +3781,7 @@ void ImGui::Shutdown(ImGuiContext* context) fclose(g.LogFile); g.LogFile = NULL; } - if (g.LogClipboard) - IM_DELETE(g.LogClipboard); + g.LogClipboard.clear(); g.Initialized = false; } @@ -3737,14 +3805,13 @@ static ImGuiWindowSettings* AddWindowSettings(const char* name) return settings; } -static void LoadIniSettingsFromDisk(const char* ini_filename) +void ImGui::LoadIniSettingsFromDisk(const char* ini_filename) { - if (!ini_filename) - return; - char* file_data = (char*)ImFileLoadToMemory(ini_filename, "rb", NULL, +1); + size_t file_data_size = 0; + char* file_data = (char*)ImFileLoadToMemory(ini_filename, "rb", &file_data_size); if (!file_data) return; - LoadIniSettingsFromMemory(file_data); + LoadIniSettingsFromMemory(file_data, (size_t)file_data_size); ImGui::MemFree(file_data); } @@ -3759,13 +3826,21 @@ ImGuiSettingsHandler* ImGui::FindSettingsHandler(const char* type_name) } // Zero-tolerance, no error reporting, cheap .ini parsing -static void LoadIniSettingsFromMemory(const char* buf_readonly) +void ImGui::LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size) { - // For convenience and to make the code simpler, we'll write zero terminators inside the buffer. So let's create a writable copy. - char* buf = ImStrdup(buf_readonly); - char* buf_end = buf + strlen(buf); - ImGuiContext& g = *GImGui; + IM_ASSERT(g.Initialized); + IM_ASSERT(g.SettingsLoaded == false && g.FrameCount == 0); + + // For user convenience, we allow passing a non zero-terminated string (hence the ini_size parameter). + // For our convenience and to make the code simpler, we'll also write zero-terminators within the buffer. So let's create a writable copy.. + if (ini_size == 0) + ini_size = strlen(ini_data); + char* buf = (char*)ImGui::MemAlloc(ini_size + 1); + char* buf_end = buf + ini_size; + memcpy(buf, ini_data, ini_size); + buf[ini_size] = 0; + void* entry_data = NULL; ImGuiSettingsHandler* entry_handler = NULL; @@ -3798,7 +3873,7 @@ static void LoadIniSettingsFromMemory(const char* buf_readonly) *type_end = 0; // Overwrite first ']' name_start++; // Skip second '[' } - entry_handler = ImGui::FindSettingsHandler(type_start); + entry_handler = FindSettingsHandler(type_start); entry_data = entry_handler ? entry_handler->ReadOpenFn(&g, entry_handler, name_start) : NULL; } else if (entry_handler != NULL && entry_data != NULL) @@ -3811,37 +3886,37 @@ static void LoadIniSettingsFromMemory(const char* buf_readonly) g.SettingsLoaded = true; } -static void SaveIniSettingsToDisk(const char* ini_filename) +void ImGui::SaveIniSettingsToDisk(const char* ini_filename) { ImGuiContext& g = *GImGui; g.SettingsDirtyTimer = 0.0f; if (!ini_filename) return; - ImVector buf; - SaveIniSettingsToMemory(buf); - + size_t ini_data_size = 0; + const char* ini_data = SaveIniSettingsToMemory(&ini_data_size); FILE* f = ImFileOpen(ini_filename, "wt"); if (!f) return; - fwrite(buf.Data, sizeof(char), (size_t)buf.Size, f); + fwrite(ini_data, sizeof(char), ini_data_size, f); fclose(f); } -static void SaveIniSettingsToMemory(ImVector& out_buf) +// Call registered handlers (e.g. SettingsHandlerWindow_WriteAll() + custom handlers) to write their stuff into a text buffer +const char* ImGui::SaveIniSettingsToMemory(size_t* out_size) { ImGuiContext& g = *GImGui; g.SettingsDirtyTimer = 0.0f; - - ImGuiTextBuffer buf; + g.SettingsIniData.Buf.resize(0); + g.SettingsIniData.Buf.push_back(0); for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++) { ImGuiSettingsHandler* handler = &g.SettingsHandlers[handler_n]; - handler->WriteAllFn(&g, handler, &buf); + handler->WriteAllFn(&g, handler, &g.SettingsIniData); } - - buf.Buf.pop_back(); // Remove extra zero-terminator used by ImGuiTextBuffer - out_buf.swap(buf.Buf); + if (out_size) + *out_size = (size_t)g.SettingsIniData.size(); + return g.SettingsIniData.c_str(); } void ImGui::MarkIniSettingsDirty() @@ -3851,7 +3926,7 @@ void ImGui::MarkIniSettingsDirty() g.SettingsDirtyTimer = g.IO.IniSavingRate; } -static void MarkIniSettingsDirty(ImGuiWindow* window) +void ImGui::MarkIniSettingsDirty(ImGuiWindow* window) { ImGuiContext& g = *GImGui; if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings)) @@ -3888,7 +3963,7 @@ static void AddWindowToSortedBuffer(ImVector* out_sorted_windows, } } -static void AddDrawListToDrawData(ImVector* out_render_list, ImDrawList* draw_list) +static void AddDrawListToDrawData(ImVector* out_list, ImDrawList* draw_list) { if (draw_list->CmdBuffer.empty()) return; @@ -3918,7 +3993,7 @@ static void AddDrawListToDrawData(ImVector* out_render_list, ImDraw if (sizeof(ImDrawIdx) == 2) IM_ASSERT(draw_list->_VtxCurrentIdx < (1 << 16) && "Too many vertices in ImDrawList using 16-bit indices. Read comment above"); - out_render_list->push_back(draw_list); + out_list->push_back(draw_list); } static void AddWindowToDrawData(ImVector* out_render_list, ImGuiWindow* window) @@ -3997,10 +4072,10 @@ void ImGui::EndFrame() return; // Notify OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME) - if (g.IO.ImeSetInputScreenPosFn && ImLengthSqr(g.OsImePosRequest - g.OsImePosSet) > 0.0001f) + if (g.IO.ImeSetInputScreenPosFn && ImLengthSqr(g.PlatformImeLastPos - g.PlatformImePos) > 0.0001f) { - g.IO.ImeSetInputScreenPosFn((int)g.OsImePosRequest.x, (int)g.OsImePosRequest.y); - g.OsImePosSet = g.OsImePosRequest; + g.IO.ImeSetInputScreenPosFn((int)g.PlatformImePos.x, (int)g.PlatformImePos.y); + g.PlatformImeLastPos = g.PlatformImePos; } // Hide implicit "Debug" window if it hasn't been used @@ -4026,7 +4101,7 @@ void ImGui::EndFrame() if (!(g.HoveredWindow->Flags & ImGuiWindowFlags_NoMove) && !(g.HoveredRootWindow->Flags & ImGuiWindowFlags_NoMove)) g.MovingWindow = g.HoveredWindow; } - else if (g.NavWindow != NULL && GetFrontMostModalRootWindow() == NULL) + else if (g.NavWindow != NULL && GetFrontMostPopupModal() == NULL) { // Clicking on void disable focus FocusWindow(NULL); @@ -4039,7 +4114,7 @@ void ImGui::EndFrame() { // Find the top-most window between HoveredWindow and the front most Modal Window. // This is where we can trim the popup stack. - ImGuiWindow* modal = GetFrontMostModalRootWindow(); + ImGuiWindow* modal = GetFrontMostPopupModal(); bool hovered_window_above_modal = false; if (modal == NULL) hovered_window_above_modal = true; @@ -4152,13 +4227,9 @@ void ImGui::LogText(const char* fmt, ...) va_list args; va_start(args, fmt); if (g.LogFile) - { vfprintf(g.LogFile, fmt, args); - } else - { - g.LogClipboard->appendfv(fmt, args); - } + g.LogClipboard.appendfv(fmt, args); va_end(args); } @@ -4234,8 +4305,7 @@ void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool text_display_end = text_end; } - const int text_len = (int)(text_display_end - text); - if (text_len > 0) + if (text != text_display_end) { window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end); if (g.LogEnabled) @@ -4251,8 +4321,7 @@ void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end if (!text_end) text_end = text + strlen(text); // FIXME-OPT - const int text_len = (int)(text_end - text); - if (text_len > 0) + if (text != text_end) { window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_end, wrap_width); if (g.LogEnabled) @@ -4498,7 +4567,7 @@ static ImGuiWindow* FindHoveredWindow() continue; // Using the clipped AABB, a child window will typically be clipped by its parent (not always) - ImRect bb(window->WindowRectClipped.Min - g.Style.TouchExtraPadding, window->WindowRectClipped.Max + g.Style.TouchExtraPadding); + ImRect bb(window->OuterRectClipped.Min - g.Style.TouchExtraPadding, window->OuterRectClipped.Max + g.Style.TouchExtraPadding); if (bb.Contains(g.IO.MousePos)) return window; } @@ -4511,12 +4580,11 @@ static ImGuiWindow* FindHoveredWindow() bool ImGui::IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip) { ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; // Clip ImRect rect_clipped(r_min, r_max); if (clip) - rect_clipped.ClipWith(window->ClipRect); + rect_clipped.ClipWith(g.CurrentWindow->ClipRect); // Expand for touch input const ImRect rect_for_touch(rect_clipped.Min - g.Style.TouchExtraPadding, rect_clipped.Max + g.Style.TouchExtraPadding); @@ -4535,7 +4603,7 @@ int ImGui::GetKeyIndex(ImGuiKey imgui_key) return GImGui->IO.KeyMap[imgui_key]; } -// Note that imgui doesn't know the semantic of each entry of io.KeyDown[]. Use your own indices/enums according to how your back-end/engine stored them into KeyDown[]! +// Note that imgui doesn't know the semantic of each entry of io.KeysDown[]. Use your own indices/enums according to how your back-end/engine stored them into io.KeysDown[]! bool ImGui::IsKeyDown(int user_key_index) { if (user_key_index < 0) return false; @@ -4610,7 +4678,7 @@ bool ImGui::IsMouseClicked(int button, bool repeat) if (repeat && t > g.IO.KeyRepeatDelay) { float delay = g.IO.KeyRepeatDelay, rate = g.IO.KeyRepeatRate; - if ((fmodf(t - delay, rate) > rate*0.5f) != (fmodf(t - delay - g.IO.DeltaTime, rate) > rate*0.5f)) + if ((ImFmod(t - delay, rate) > rate*0.5f) != (ImFmod(t - delay - g.IO.DeltaTime, rate) > rate*0.5f)) return true; } @@ -4848,7 +4916,7 @@ void ImGui::OpenPopupEx(ImGuiID id) popup_ref.OpenFrameCount = g.FrameCount; popup_ref.OpenParentId = parent_window->IDStack.back(); popup_ref.OpenMousePos = g.IO.MousePos; - popup_ref.OpenPopupPos = (!g.NavDisableHighlight && g.NavDisableMouseHover) ? NavCalcPreferredMousePos() : g.IO.MousePos; + popup_ref.OpenPopupPos = NavCalcPreferredRefPos(); //printf("[%05d] OpenPopupEx(0x%08X)\n", g.FrameCount, id); if (g.OpenPopupStack.Size < current_stack_size + 1) @@ -4913,7 +4981,7 @@ void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window) ClosePopupToLevel(n); } -static ImGuiWindow* GetFrontMostModalRootWindow() +ImGuiWindow* ImGui::GetFrontMostPopupModal() { ImGuiContext& g = *GImGui; for (int n = g.OpenPopupStack.Size-1; n >= 0; n--) @@ -5058,7 +5126,7 @@ bool ImGui::OpenPopupOnItemClick(const char* str_id, int mouse_button) if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) { ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! - IM_ASSERT(id != 0); // However, you cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) + IM_ASSERT(id != 0); // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) OpenPopupEx(id); return true; } @@ -5072,7 +5140,7 @@ bool ImGui::BeginPopupContextItem(const char* str_id, int mouse_button) { ImGuiWindow* window = GImGui->CurrentWindow; ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! - IM_ASSERT(id != 0); // However, you cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) + IM_ASSERT(id != 0); // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) OpenPopupEx(id); return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); @@ -5168,8 +5236,7 @@ void ImGui::EndChild() } else { - // When using auto-filling child window, we don't provide full width/height to ItemSize so that it doesn't feed back into automatic size-fitting. - ImVec2 sz = GetWindowSize(); + ImVec2 sz = window->Size; if (window->AutoFitChildAxises & (1 << ImGuiAxis_X)) // Arbitrary minimum zero-ish child size of 4.0f causes less trouble than a 0.0f sz.x = ImMax(4.0f, sz.x); if (window->AutoFitChildAxises & (1 << ImGuiAxis_Y)) @@ -5224,9 +5291,10 @@ static void CheckStacksSize(ImGuiWindow* window, bool write) { int current = window->IDStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushID/PopID or TreeNode/TreePop Mismatch!"); p_backup++; } // Too few or too many PopID()/TreePop() { int current = window->DC.GroupStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "BeginGroup/EndGroup Mismatch!"); p_backup++; } // Too few or too many 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++;}// Too few or too many EndMenu()/EndPopup() - { int current = g.ColorModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushStyleColor/PopStyleColor Mismatch!"); p_backup++; } // Too few or too many PopStyleColor() - { int current = g.StyleModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushStyleVar/PopStyleVar Mismatch!"); p_backup++; } // Too few or too many PopStyleVar() - { int current = g.FontStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushFont/PopFont Mismatch!"); p_backup++; } // Too few or too many PopFont() + // For color, style and font stacks there is an incentive to use Push/Begin/Pop/.../End patterns, so we relax our checks a little to allow them. + { int current = g.ColorModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup >= current && "PushStyleColor/PopStyleColor Mismatch!"); p_backup++; } // Too few or too many PopStyleColor() + { int current = g.StyleModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup >= current && "PushStyleVar/PopStyleVar Mismatch!"); p_backup++; } // Too few or too many PopStyleVar() + { int current = g.FontStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup >= current && "PushFont/PopFont Mismatch!"); p_backup++; } // Too few or too many PopFont() IM_ASSERT(p_backup == window->DC.StackSizesBackup + IM_ARRAYSIZE(window->DC.StackSizesBackup)); } @@ -5236,15 +5304,18 @@ enum ImGuiPopupPositionPolicy ImGuiPopupPositionPolicy_ComboBox }; -static ImVec2 FindBestWindowPosForPopup(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy = ImGuiPopupPositionPolicy_Default) +static ImRect FindAllowedExtentRectForWindow(ImGuiWindow*) +{ + ImVec2 padding = GImGui->Style.DisplaySafeAreaPadding; + ImRect r_screen = GetViewportRect(); + r_screen.Expand(ImVec2((r_screen.GetWidth() > padding.x * 2) ? -padding.x : 0.0f, (r_screen.GetHeight() > padding.y * 2) ? -padding.y : 0.0f)); + return r_screen; +} + +// r_avoid = the rectangle to avoid (e.g. for tooltip it is a rectangle around the mouse cursor which we want to avoid. for popups it's a small point around the cursor.) +// r_outer = the visible area rectangle, minus safe area padding. If our popup size won't fit because of safe area padding we ignore it. +static ImVec2 FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy = ImGuiPopupPositionPolicy_Default) { - const ImGuiStyle& style = GImGui->Style; - - // r_avoid = the rectangle to avoid (e.g. for tooltip it is a rectangle around the mouse cursor which we want to avoid. for popups it's a small point around the cursor.) - // r_outer = the visible area rectangle, minus safe area padding. If our popup size won't fit because of safe area padding we ignore it. - ImVec2 safe_padding = style.DisplaySafeAreaPadding; - ImRect r_outer(GetViewportRect()); - r_outer.Expand(ImVec2((size.x - r_outer.GetWidth() > safe_padding.x*2) ? -safe_padding.x : 0.0f, (size.y - r_outer.GetHeight() > safe_padding.y*2) ? -safe_padding.y : 0.0f)); ImVec2 base_pos_clamped = ImClamp(ref_pos, r_outer.Min, r_outer.Max - size); //GImGui->OverlayDrawList.AddRect(r_avoid.Min, r_avoid.Max, IM_COL32(255,0,0,255)); //GImGui->OverlayDrawList.AddRect(r_outer.Min, r_outer.Max, IM_COL32(0,255,0,255)); @@ -5296,6 +5367,49 @@ static ImVec2 FindBestWindowPosForPopup(const ImVec2& ref_pos, const ImVec2& siz return pos; } +static ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + + ImRect r_outer = FindAllowedExtentRectForWindow(window); + if (window->Flags & ImGuiWindowFlags_ChildMenu) + { + // Child menus typically request _any_ position within the parent menu item, and then our FindBestWindowPosForPopup() function will move the new menu outside the parent bounds. + // This is how we end up with child menus appearing (most-commonly) on the right of the parent menu. + IM_ASSERT(g.CurrentWindow == window); + ImGuiWindow* parent_window = g.CurrentWindowStack[g.CurrentWindowStack.Size - 2]; + float horizontal_overlap = g.Style.ItemSpacing.x; // We want some overlap to convey the relative depth of each menu (currently the amount of overlap is hard-coded to style.ItemSpacing.x). + ImRect r_avoid; + if (parent_window->DC.MenuBarAppending) + r_avoid = ImRect(-FLT_MAX, parent_window->Pos.y + parent_window->TitleBarHeight(), FLT_MAX, parent_window->Pos.y + parent_window->TitleBarHeight() + parent_window->MenuBarHeight()); + else + r_avoid = ImRect(parent_window->Pos.x + horizontal_overlap, -FLT_MAX, parent_window->Pos.x + parent_window->Size.x - horizontal_overlap - parent_window->ScrollbarSizes.x, FLT_MAX); + return FindBestWindowPosForPopupEx(window->Pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid); + } + if (window->Flags & ImGuiWindowFlags_Popup) + { + ImRect r_avoid = ImRect(window->Pos.x - 1, window->Pos.y - 1, window->Pos.x + 1, window->Pos.y + 1); + return FindBestWindowPosForPopupEx(window->Pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid); + } + if (window->Flags & ImGuiWindowFlags_Tooltip) + { + // Position tooltip (always follows mouse) + float sc = g.Style.MouseCursorScale; + ImVec2 ref_pos = NavCalcPreferredRefPos(); + ImRect r_avoid; + if (!g.NavDisableHighlight && g.NavDisableMouseHover && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos)) + r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 16, ref_pos.y + 8); + else + r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24 * sc, ref_pos.y + 24 * sc); // FIXME: Hard-coded based on mouse cursor shape expectation. Exact dimension not very important. + ImVec2 pos = FindBestWindowPosForPopupEx(ref_pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid); + if (window->AutoPosLastDirection == ImGuiDir_None) + pos = ref_pos + ImVec2(2, 2); // If there's not enough room, for tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible. + return pos; + } + IM_ASSERT(0); + return window->Pos; +} + static void SetWindowConditionAllowFlags(ImGuiWindow* window, ImGuiCond flags, bool enabled) { window->SetWindowPosAllowFlags = enabled ? (window->SetWindowPosAllowFlags | flags) : (window->SetWindowPosAllowFlags & ~flags); @@ -5319,21 +5433,20 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl window->Flags = flags; g.WindowsById.SetVoidPtr(window->ID, window); + // Default/arbitrary window position. Use SetNextWindowPos() with the appropriate condition flag to change the initial position of a window. + window->Pos = ImVec2(60, 60); + // User can disable loading and saving of settings. Tooltip and child windows also don't store settings. if (!(flags & ImGuiWindowFlags_NoSavedSettings)) { // Retrieve settings from .ini file - // Use SetWindowPos() or SetNextWindowPos() with the appropriate condition flag to change the initial position of a window. - window->Pos = window->PosFloat = ImVec2(60, 60); - if (ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID)) { SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false); - window->PosFloat = settings->Pos; - window->Pos = ImFloor(window->PosFloat); + window->Pos = ImFloor(settings->Pos); window->Collapsed = settings->Collapsed; if (ImLengthSqr(settings->Size) > 0.00001f) - size = settings->Size; + size = ImFloor(settings->Size); } } window->Size = window->SizeFull = window->SizeFullAtLastBegin = size; @@ -5401,24 +5514,22 @@ static ImVec2 CalcSizeAutoFit(ImGuiWindow* window, const ImVec2& size_contents) { ImGuiContext& g = *GImGui; ImGuiStyle& style = g.Style; - ImGuiWindowFlags flags = window->Flags; - ImVec2 size_auto_fit; - if ((flags & ImGuiWindowFlags_Tooltip) != 0) + if (window->Flags & ImGuiWindowFlags_Tooltip) { - // Tooltip always resize. We keep the spacing symmetric on both axises for aesthetic purpose. - size_auto_fit = size_contents; + // Tooltip always resize + return size_contents; } else { // When the window cannot fit all contents (either because of constraints, either because screen is too small): we are growing the size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than DisplaySize-WindowPadding. - size_auto_fit = ImClamp(size_contents, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - g.Style.DisplaySafeAreaPadding)); + ImVec2 size_auto_fit = ImClamp(size_contents, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - g.Style.DisplaySafeAreaPadding * 2.0f)); ImVec2 size_auto_fit_after_constraint = CalcSizeAfterConstraint(window, size_auto_fit); - if (size_auto_fit_after_constraint.x < size_contents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)) + if (size_auto_fit_after_constraint.x < size_contents.x && !(window->Flags & ImGuiWindowFlags_NoScrollbar) && (window->Flags & ImGuiWindowFlags_HorizontalScrollbar)) size_auto_fit.y += style.ScrollbarSize; - if (size_auto_fit_after_constraint.y < size_contents.y && !(flags & ImGuiWindowFlags_NoScrollbar)) + if (size_auto_fit_after_constraint.y < size_contents.y && !(window->Flags & ImGuiWindowFlags_NoScrollbar)) size_auto_fit.x += style.ScrollbarSize; + return size_auto_fit; } - return size_auto_fit; } static float GetScrollMaxX(ImGuiWindow* window) @@ -5431,15 +5542,26 @@ static float GetScrollMaxY(ImGuiWindow* window) return ImMax(0.0f, window->SizeContents.y - (window->SizeFull.y - window->ScrollbarSizes.y)); } -static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window) +static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool snap_on_edges) { + ImGuiContext& g = *GImGui; ImVec2 scroll = window->Scroll; - float cr_x = window->ScrollTargetCenterRatio.x; - float cr_y = window->ScrollTargetCenterRatio.y; if (window->ScrollTarget.x < FLT_MAX) + { + float cr_x = window->ScrollTargetCenterRatio.x; scroll.x = window->ScrollTarget.x - cr_x * (window->SizeFull.x - window->ScrollbarSizes.x); + } if (window->ScrollTarget.y < FLT_MAX) - scroll.y = window->ScrollTarget.y - (1.0f - cr_y) * (window->TitleBarHeight() + window->MenuBarHeight()) - cr_y * (window->SizeFull.y - window->ScrollbarSizes.y); + { + // 'snap_on_edges' allows for a discontinuity at the edge of scrolling limits to take account of WindowPadding so that scrolling to make the last item visible scroll far enough to see the padding. + float cr_y = window->ScrollTargetCenterRatio.y; + float target_y = window->ScrollTarget.y; + if (snap_on_edges && cr_y <= 0.0f && target_y <= window->WindowPadding.y) + target_y = 0.0f; + if (snap_on_edges && cr_y >= 1.0f && target_y >= window->SizeContents.y - window->WindowPadding.y + g.Style.ItemSpacing.y) + target_y = window->SizeContents.y; + scroll.y = target_y - (1.0f - cr_y) * (window->TitleBarHeight() + window->MenuBarHeight()) - cr_y * (window->SizeFull.y - window->ScrollbarSizes.y); + } scroll = ImMax(scroll, ImVec2(0.0f, 0.0f)); if (!window->Collapsed && !window->SkipItems) { @@ -5474,9 +5596,9 @@ static void CalcResizePosSizeFromAnyCorner(ImGuiWindow* window, const ImVec2& co struct ImGuiResizeGripDef { - ImVec2 CornerPos; - ImVec2 InnerDir; - int AngleMin12, AngleMax12; + ImVec2 CornerPos; + ImVec2 InnerDir; + int AngleMin12, AngleMax12; }; const ImGuiResizeGripDef resize_grip_def[4] = @@ -5523,7 +5645,8 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au // Using the FlattenChilds button flag we make the resize button accessible even if we are hovering over a child window ImRect resize_rect(corner, corner + grip.InnerDir * grip_hover_size); - resize_rect.FixInverted(); + if (resize_rect.Min.x > resize_rect.Max.x) ImSwap(resize_rect.Min.x, resize_rect.Max.x); + if (resize_rect.Min.y > resize_rect.Max.y) ImSwap(resize_rect.Min.y, resize_rect.Max.y); bool hovered, held; ButtonBehavior(resize_rect, window->GetID((void*)(intptr_t)resize_grip_n), &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus); if (hovered || held) @@ -5598,7 +5721,7 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au } if (pos_target.x != FLT_MAX) { - window->Pos = window->PosFloat = ImFloor(pos_target); + window->Pos = ImFloor(pos_target); MarkIniSettingsDirty(window); } @@ -5695,14 +5818,12 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { SetWindowPos(window, g.NextWindowData.PosVal, g.NextWindowData.PosCond); } - g.NextWindowData.PosCond = 0; } if (g.NextWindowData.SizeCond) { window_size_x_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindowData.SizeCond) != 0 && (g.NextWindowData.SizeVal.x > 0.0f); window_size_y_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindowData.SizeCond) != 0 && (g.NextWindowData.SizeVal.y > 0.0f); SetWindowSize(window, g.NextWindowData.SizeVal, g.NextWindowData.SizeCond); - g.NextWindowData.SizeCond = 0; } if (g.NextWindowData.ContentSizeCond) { @@ -5710,22 +5831,15 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->SizeContentsExplicit = g.NextWindowData.ContentSizeVal; if (window->SizeContentsExplicit.y != 0.0f) window->SizeContentsExplicit.y += window->TitleBarHeight() + window->MenuBarHeight(); - g.NextWindowData.ContentSizeCond = 0; } else if (first_begin_of_the_frame) { window->SizeContentsExplicit = ImVec2(0.0f, 0.0f); } if (g.NextWindowData.CollapsedCond) - { SetWindowCollapsed(window, g.NextWindowData.CollapsedVal, g.NextWindowData.CollapsedCond); - g.NextWindowData.CollapsedCond = 0; - } if (g.NextWindowData.FocusCond) - { - SetWindowFocus(); - g.NextWindowData.FocusCond = 0; - } + FocusWindow(window); if (window->Appearing) SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, false); @@ -5752,12 +5866,41 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->LastFrameActive = current_frame; window->IDStack.resize(1); - // Lock window rounding, border size and rounding so that altering the border sizes for children doesn't have side-effects. - window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding; + // UPDATE CONTENTS SIZE, UPDATE HIDDEN STATUS + + // Update contents size from last frame for auto-fitting (or use explicit size) + window->SizeContents = CalcSizeContents(window); + if (window->HiddenFrames > 0) + window->HiddenFrames--; + + // Hide new windows for one frame until they calculate their size + if (window_just_created && (!window_size_x_set_by_api || !window_size_y_set_by_api)) + window->HiddenFrames = 1; + + // Hide popup/tooltip window when re-opening while we measure size (because we recycle the windows) + // We reset Size/SizeContents for reappearing popups/tooltips early in this function, so further code won't be tempted to use the old size. + if (window_just_activated_by_user && (flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) != 0) + { + window->HiddenFrames = 1; + if (flags & ImGuiWindowFlags_AlwaysAutoResize) + { + if (!window_size_x_set_by_api) + window->Size.x = window->SizeFull.x = 0.f; + if (!window_size_y_set_by_api) + window->Size.y = window->SizeFull.y = 0.f; + window->SizeContents = ImVec2(0.f, 0.f); + } + } + + SetCurrentWindow(window); + + // Lock border size and padding for the frame (so that altering them doesn't cause inconsistencies) window->WindowBorderSize = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildBorderSize : ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupBorderSize : style.WindowBorderSize; window->WindowPadding = style.WindowPadding; if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_Popup)) && window->WindowBorderSize == 0.0f) window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f); + window->DC.MenuBarOffset.x = ImMax(ImMax(window->WindowPadding.x, style.ItemSpacing.x), g.NextWindowData.MenuBarOffsetMinVal.x); + window->DC.MenuBarOffset.y = g.NextWindowData.MenuBarOffsetMinVal.y; // Collapse window by double-clicking on title bar // At this point we don't have a clipping rectangle setup yet, so we can use the title bar area for hit detection and drawing @@ -5779,29 +5922,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // SIZE - // Update contents size from last frame for auto-fitting (unless explicitly specified) - window->SizeContents = CalcSizeContents(window); - - // Hide popup/tooltip window when re-opening while we measure size (because we recycle the windows) - if (window->HiddenFrames > 0) - window->HiddenFrames--; - if (window_just_activated_by_user && (flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) != 0) - { - window->HiddenFrames = 1; - if (flags & ImGuiWindowFlags_AlwaysAutoResize) - { - if (!window_size_x_set_by_api) - window->Size.x = window->SizeFull.x = 0.f; - if (!window_size_y_set_by_api) - window->Size.y = window->SizeFull.y = 0.f; - window->SizeContents = ImVec2(0.f, 0.f); - } - } - - // Hide new windows for one frame until they calculate their size - if (window_just_created && (!window_size_x_set_by_api || !window_size_y_set_by_api)) - window->HiddenFrames = 1; - // Calculate auto-fit size, handle automatic resize const ImVec2 size_auto_fit = CalcSizeAutoFit(window, window->SizeContents); ImVec2 size_full_modified(FLT_MAX, FLT_MAX); @@ -5851,7 +5971,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { window->AutoPosLastDirection = ImGuiDir_None; if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api) - window->Pos = window->PosFloat = g.CurrentPopupStack.back().OpenPopupPos; + window->Pos = g.CurrentPopupStack.back().OpenPopupPos; } // Position child window @@ -5860,67 +5980,33 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->BeginOrderWithinParent = parent_window->DC.ChildWindows.Size; parent_window->DC.ChildWindows.push_back(window); if (!(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api && !window_is_child_tooltip) - window->Pos = window->PosFloat = parent_window->DC.CursorPos; + window->Pos = parent_window->DC.CursorPos; } const bool window_pos_with_pivot = (window->SetWindowPosVal.x != FLT_MAX && window->HiddenFrames == 0); if (window_pos_with_pivot) - { - // Position given a pivot (e.g. for centering) - SetWindowPos(window, ImMax(style.DisplaySafeAreaPadding, window->SetWindowPosVal - window->SizeFull * window->SetWindowPosPivot), 0); - } - else if (flags & ImGuiWindowFlags_ChildMenu) - { - // Child menus typically request _any_ position within the parent menu item, and then our FindBestPopupWindowPos() function will move the new menu outside the parent bounds. - // This is how we end up with child menus appearing (most-commonly) on the right of the parent menu. - IM_ASSERT(window_pos_set_by_api); - float horizontal_overlap = style.ItemSpacing.x; // We want some overlap to convey the relative depth of each popup (currently the amount of overlap it is hard-coded to style.ItemSpacing.x, may need to introduce another style value). - ImGuiWindow* parent_menu = parent_window_in_stack; - ImRect rect_to_avoid; - if (parent_menu->DC.MenuBarAppending) - rect_to_avoid = ImRect(-FLT_MAX, parent_menu->Pos.y + parent_menu->TitleBarHeight(), FLT_MAX, parent_menu->Pos.y + parent_menu->TitleBarHeight() + parent_menu->MenuBarHeight()); - else - rect_to_avoid = ImRect(parent_menu->Pos.x + horizontal_overlap, -FLT_MAX, parent_menu->Pos.x + parent_menu->Size.x - horizontal_overlap - parent_menu->ScrollbarSizes.x, FLT_MAX); - window->PosFloat = FindBestWindowPosForPopup(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid); - } + SetWindowPos(window, ImMax(style.DisplaySafeAreaPadding, window->SetWindowPosVal - window->SizeFull * window->SetWindowPosPivot), 0); // Position given a pivot (e.g. for centering) + else if ((flags & ImGuiWindowFlags_ChildMenu) != 0) + window->Pos = FindBestWindowPosForPopup(window); else if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api && window_just_appearing_after_hidden_for_resize) - { - ImRect rect_to_avoid(window->PosFloat.x - 1, window->PosFloat.y - 1, window->PosFloat.x + 1, window->PosFloat.y + 1); - window->PosFloat = FindBestWindowPosForPopup(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid); - } - - // Position tooltip (always follows mouse) - if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api && !window_is_child_tooltip) - { - float sc = g.Style.MouseCursorScale; - ImVec2 ref_pos = (!g.NavDisableHighlight && g.NavDisableMouseHover) ? NavCalcPreferredMousePos() : g.IO.MousePos; - ImRect rect_to_avoid; - if (!g.NavDisableHighlight && g.NavDisableMouseHover && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos)) - rect_to_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 16, ref_pos.y + 8); - else - rect_to_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24 * sc, ref_pos.y + 24 * sc); // FIXME: Hard-coded based on mouse cursor shape expectation. Exact dimension not very important. - window->PosFloat = FindBestWindowPosForPopup(ref_pos, window->Size, &window->AutoPosLastDirection, rect_to_avoid); - if (window->AutoPosLastDirection == ImGuiDir_None) - window->PosFloat = ref_pos + ImVec2(2,2); // If there's not enough room, for tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible. - } + window->Pos = FindBestWindowPosForPopup(window); + else if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api && !window_is_child_tooltip) + window->Pos = FindBestWindowPosForPopup(window); // Clamp position so it stays visible - if (!(flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Tooltip)) + if (!(flags & ImGuiWindowFlags_ChildWindow)) { if (!window_pos_set_by_api && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0 && g.IO.DisplaySize.x > 0.0f && g.IO.DisplaySize.y > 0.0f) // Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing. { ImVec2 padding = ImMax(style.DisplayWindowPadding, style.DisplaySafeAreaPadding); - window->PosFloat = ImMax(window->PosFloat + window->Size, padding) - window->Size; - window->PosFloat = ImMin(window->PosFloat, g.IO.DisplaySize - padding); + window->Pos = ImMax(window->Pos + window->Size, padding) - window->Size; + window->Pos = ImMin(window->Pos, g.IO.DisplaySize - padding); } } - window->Pos = ImFloor(window->PosFloat); + window->Pos = ImFloor(window->Pos); - // Default item width. Make it proportional to window size if window manually resizes - if (window->Size.x > 0.0f && !(flags & ImGuiWindowFlags_Tooltip) && !(flags & ImGuiWindowFlags_AlwaysAutoResize)) - window->ItemWidthDefault = (float)(int)(window->Size.x * 0.65f); - else - window->ItemWidthDefault = (float)(int)(g.FontSize * 16.0f); + // Lock window rounding for the frame (so that altering them doesn't cause inconsistencies) + window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding; // Prepare for focus requests window->FocusIdxAllRequestCurrent = (window->FocusIdxAllRequestNext == INT_MAX || window->FocusIdxAllCounter == -1) ? INT_MAX : (window->FocusIdxAllRequestNext + (window->FocusIdxAllCounter+1)) % (window->FocusIdxAllCounter+1); @@ -5929,7 +6015,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->FocusIdxAllRequestNext = window->FocusIdxTabRequestNext = INT_MAX; // Apply scrolling - window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window); + window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window, true); window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); // Apply focus, new windows appears in front @@ -5946,6 +6032,12 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (!window->Collapsed) UpdateManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0]); + // Default item width. Make it proportional to window size if window manually resizes + if (window->Size.x > 0.0f && !(flags & ImGuiWindowFlags_Tooltip) && !(flags & ImGuiWindowFlags_AlwaysAutoResize)) + window->ItemWidthDefault = (float)(int)(window->Size.x * 0.65f); + else + window->ItemWidthDefault = (float)(int)(g.FontSize * 16.0f); + // DRAWING // Setup draw list and outer clipping rectangle @@ -5959,7 +6051,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) PushClipRect(viewport_rect.Min, viewport_rect.Max, true); // Draw modal window background (darkens what is behind them) - if ((flags & ImGuiWindowFlags_Modal) != 0 && window == GetFrontMostModalRootWindow()) + if ((flags & ImGuiWindowFlags_Modal) != 0 && window == GetFrontMostPopupModal()) window->DrawList->AddRectFilled(viewport_rect.Min, viewport_rect.Max, GetColorU32(ImGuiCol_ModalWindowDarkening, g.ModalWindowDarkeningRatio)); // Draw navigation selection/windowing rectangle background @@ -6033,7 +6125,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Borders if (window_border_size > 0.0f) - window->DrawList->AddRect(window->Pos, window->Pos+window->Size, GetColorU32(ImGuiCol_Border), window_rounding, ImDrawCornerFlags_All, window_border_size); + window->DrawList->AddRect(window->Pos, window->Pos + window->Size, GetColorU32(ImGuiCol_Border), window_rounding, ImDrawCornerFlags_All, window_border_size); if (border_held != -1) { ImRect border = GetBorderRect(window, border_held, grip_draw_size, 0.0f); @@ -6060,11 +6152,12 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Store a backup of SizeFull which we will use next frame to decide if we need scrollbars. window->SizeFullAtLastBegin = window->SizeFull; - // Update ContentsRegionMax. All the variable it depends on are set above in this function. - window->ContentsRegionRect.Min.x = -window->Scroll.x + window->WindowPadding.x; - window->ContentsRegionRect.Min.y = -window->Scroll.y + window->WindowPadding.y + window->TitleBarHeight() + window->MenuBarHeight(); - window->ContentsRegionRect.Max.x = -window->Scroll.x - window->WindowPadding.x + (window->SizeContentsExplicit.x != 0.0f ? window->SizeContentsExplicit.x : (window->Size.x - window->ScrollbarSizes.x)); - window->ContentsRegionRect.Max.y = -window->Scroll.y - window->WindowPadding.y + (window->SizeContentsExplicit.y != 0.0f ? window->SizeContentsExplicit.y : (window->Size.y - window->ScrollbarSizes.y)); + // Update various regions. Variables they depends on are set above in this function. + // FIXME: window->ContentsRegion.Max is currently very misleading / partly faulty, but some BeginChild() patterns relies on it. + window->ContentsRegionRect.Min.x = window->Pos.x - window->Scroll.x + window->WindowPadding.x; + window->ContentsRegionRect.Min.y = window->Pos.y - window->Scroll.y + window->WindowPadding.y + window->TitleBarHeight() + window->MenuBarHeight(); + window->ContentsRegionRect.Max.x = window->Pos.x - window->Scroll.x - window->WindowPadding.x + (window->SizeContentsExplicit.x != 0.0f ? window->SizeContentsExplicit.x : (window->Size.x - window->ScrollbarSizes.x)); + window->ContentsRegionRect.Max.y = window->Pos.y - window->Scroll.y - window->WindowPadding.y + (window->SizeContentsExplicit.y != 0.0f ? window->SizeContentsExplicit.y : (window->Size.y - window->ScrollbarSizes.y)); // Setup drawing context // (NB: That term "drawing context / DC" lost its meaning a long time ago. Initially was meant to hold transient data only. Nowadays difference between window-> and window->DC-> is dubious.) @@ -6082,7 +6175,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->DC.NavLayerActiveMask = window->DC.NavLayerActiveMaskNext; window->DC.NavLayerActiveMaskNext = 0x00; window->DC.MenuBarAppending = false; - window->DC.MenuBarOffsetX = ImMax(window->WindowPadding.x, style.ItemSpacing.x); window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; window->DC.ChildWindows.resize(0); window->DC.LayoutType = ImGuiLayoutType_Vertical; @@ -6132,7 +6224,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { ImGuiID id = window->GetID("#COLLAPSE"); ImRect bb(window->Pos + style.FramePadding + ImVec2(1,1), window->Pos + style.FramePadding + ImVec2(g.FontSize,g.FontSize) - ImVec2(1,1)); - ItemAdd(bb, id); // To allow navigation + ItemAdd(bb, id); if (ButtonBehavior(bb, id, NULL, NULL)) window->CollapseToggleWanted = true; // Defer collapsing to next frame as we are too far in the Begin() function RenderNavHighlight(bb, id); @@ -6152,12 +6244,13 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->DC.NavLayerCurrentMask >>= 1; window->DC.ItemFlags = item_flags_backup; - // Title text (FIXME: refactor text alignment facilities along with RenderText helpers) + // Title text (FIXME: refactor text alignment facilities along with RenderText helpers, this is too much code for what it does.) ImVec2 text_size = CalcTextSize(name, NULL, true); ImRect text_r = title_bar_rect; - float pad_left = (flags & ImGuiWindowFlags_NoCollapse) == 0 ? (style.FramePadding.x + g.FontSize + style.ItemInnerSpacing.x) : style.FramePadding.x; - float pad_right = (p_open != NULL) ? (style.FramePadding.x + g.FontSize + style.ItemInnerSpacing.x) : style.FramePadding.x; - if (style.WindowTitleAlign.x > 0.0f) pad_right = ImLerp(pad_right, pad_left, style.WindowTitleAlign.x); + float pad_left = (flags & ImGuiWindowFlags_NoCollapse) ? style.FramePadding.x : (style.FramePadding.x + g.FontSize + style.ItemInnerSpacing.x); + float pad_right = (p_open == NULL) ? style.FramePadding.x : (style.FramePadding.x + g.FontSize + style.ItemInnerSpacing.x); + if (style.WindowTitleAlign.x > 0.0f) + pad_right = ImLerp(pad_right, pad_left, style.WindowTitleAlign.x); text_r.Min.x += pad_left; text_r.Max.x -= pad_right; ImRect clip_rect = text_r; @@ -6166,8 +6259,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } // Save clipped aabb so we can access it in constant-time in FindHoveredWindow() - window->WindowRectClipped = window->Rect(); - window->WindowRectClipped.ClipWith(window->ClipRect); + window->OuterRectClipped = window->Rect(); + window->OuterRectClipped.ClipWith(window->ClipRect); // Pressing CTRL+C while holding on a window copy its content to the clipboard // This works but 1. doesn't handle multiple Begin/End pairs, 2. recursing into another Begin/End pair - so we need to work that out and add better logging scope. @@ -6180,21 +6273,21 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Inner rectangle // We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame - // Note that if our window is collapsed we will end up with a null clipping rectangle which is the correct behavior. - window->InnerRect.Min.x = title_bar_rect.Min.x + window->WindowBorderSize; - window->InnerRect.Min.y = title_bar_rect.Max.y + window->MenuBarHeight() + (((flags & ImGuiWindowFlags_MenuBar) || !(flags & ImGuiWindowFlags_NoTitleBar)) ? style.FrameBorderSize : window->WindowBorderSize); - window->InnerRect.Max.x = window->Pos.x + window->Size.x - window->ScrollbarSizes.x - window->WindowBorderSize; - window->InnerRect.Max.y = window->Pos.y + window->Size.y - window->ScrollbarSizes.y - window->WindowBorderSize; + // Note that if our window is collapsed we will end up with an inverted (~null) clipping rectangle which is the correct behavior. + window->InnerMainRect.Min.x = title_bar_rect.Min.x + window->WindowBorderSize; + window->InnerMainRect.Min.y = title_bar_rect.Max.y + window->MenuBarHeight() + (((flags & ImGuiWindowFlags_MenuBar) || !(flags & ImGuiWindowFlags_NoTitleBar)) ? style.FrameBorderSize : window->WindowBorderSize); + window->InnerMainRect.Max.x = window->Pos.x + window->Size.x - window->ScrollbarSizes.x - window->WindowBorderSize; + window->InnerMainRect.Max.y = window->Pos.y + window->Size.y - window->ScrollbarSizes.y - window->WindowBorderSize; //window->DrawList->AddRect(window->InnerRect.Min, window->InnerRect.Max, IM_COL32_WHITE); // Inner clipping rectangle // Force round operator last to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. - window->InnerClipRect.Min.x = ImFloor(0.5f + window->InnerRect.Min.x + ImMax(0.0f, ImFloor(window->WindowPadding.x*0.5f - window->WindowBorderSize))); - window->InnerClipRect.Min.y = ImFloor(0.5f + window->InnerRect.Min.y); - window->InnerClipRect.Max.x = ImFloor(0.5f + window->InnerRect.Max.x - ImMax(0.0f, ImFloor(window->WindowPadding.x*0.5f - window->WindowBorderSize))); - window->InnerClipRect.Max.y = ImFloor(0.5f + window->InnerRect.Max.y); + window->InnerClipRect.Min.x = ImFloor(0.5f + window->InnerMainRect.Min.x + ImMax(0.0f, ImFloor(window->WindowPadding.x*0.5f - window->WindowBorderSize))); + window->InnerClipRect.Min.y = ImFloor(0.5f + window->InnerMainRect.Min.y); + window->InnerClipRect.Max.x = ImFloor(0.5f + window->InnerMainRect.Max.x - ImMax(0.0f, ImFloor(window->WindowPadding.x*0.5f - window->WindowBorderSize))); + window->InnerClipRect.Max.y = ImFloor(0.5f + window->InnerMainRect.Max.y); - // After Begin() we fill the last item / hovered data using the title bar data. Make that a standard behavior (to allow usage of context menus on title bar only, etc.). + // After Begin() we fill the last item / hovered data based on title bar data. It is a standard behavior (to allow creation of context menus on title bar only, etc.). window->DC.LastItemId = window->MoveId; window->DC.LastItemStatusFlags = IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0; window->DC.LastItemRect = title_bar_rect; @@ -6207,17 +6300,17 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->WriteAccessed = false; window->BeginCount++; - g.NextWindowData.SizeConstraintCond = 0; + g.NextWindowData.Clear(); // 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). + // Mark them as collapsed so commands are skipped earlier (we can't manually collapse them because they have no title bar). if (flags & ImGuiWindowFlags_ChildWindow) { IM_ASSERT((flags & ImGuiWindowFlags_NoTitleBar) != 0); window->Collapsed = parent_window && parent_window->Collapsed; if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0) - window->Collapsed |= (window->WindowRectClipped.Min.x >= window->WindowRectClipped.Max.x || window->WindowRectClipped.Min.y >= window->WindowRectClipped.Max.y); + window->Collapsed |= (window->OuterRectClipped.Min.x >= window->OuterRectClipped.Max.x || window->OuterRectClipped.Min.y >= window->OuterRectClipped.Max.y); // We also hide the window from rendering because we've already added its border to the command list. // (we could perform the check earlier in the function but it is simpler at this point) @@ -6883,7 +6976,6 @@ static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond) // Set const ImVec2 old_pos = window->Pos; - window->PosFloat = pos; window->Pos = ImFloor(pos); window->DC.CursorPos += (window->Pos - old_pos); // As we happen to move the window while it is being appended to (which is a bad idea - will smear) let's at least offset the cursor window->DC.CursorMaxPos += (window->Pos - old_pos); // And more importantly we need to adjust this so size calculation doesn't get affected. @@ -7060,7 +7152,7 @@ void ImGui::SetNextWindowBgAlpha(float alpha) ImVec2 ImGui::GetContentRegionMax() { ImGuiWindow* window = GetCurrentWindowRead(); - ImVec2 mx = window->ContentsRegionRect.Max; + ImVec2 mx = window->ContentsRegionRect.Max - window->Pos; if (window->DC.ColumnsSet) mx.x = GetColumnOffset(window->DC.ColumnsSet->Current + 1) - window->WindowPadding.x; return mx; @@ -7081,19 +7173,19 @@ float ImGui::GetContentRegionAvailWidth() ImVec2 ImGui::GetWindowContentRegionMin() { ImGuiWindow* window = GetCurrentWindowRead(); - return window->ContentsRegionRect.Min; + return window->ContentsRegionRect.Min - window->Pos; } ImVec2 ImGui::GetWindowContentRegionMax() { ImGuiWindow* window = GetCurrentWindowRead(); - return window->ContentsRegionRect.Max; + return window->ContentsRegionRect.Max - window->Pos; } float ImGui::GetWindowContentRegionWidth() { ImGuiWindow* window = GetCurrentWindowRead(); - return window->ContentsRegionRect.Max.x - window->ContentsRegionRect.Min.x; + return window->ContentsRegionRect.GetWidth(); } float ImGui::GetTextLineHeight() @@ -7250,12 +7342,6 @@ void ImGui::SetScrollFromPosY(float pos_y, float center_y_ratio) IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f); window->ScrollTarget.y = (float)(int)(pos_y + window->Scroll.y); window->ScrollTargetCenterRatio.y = center_y_ratio; - - // Minor hack to to make scrolling to top/bottom of window take account of WindowPadding, it looks more right to the user this way - if (center_y_ratio <= 0.0f && window->ScrollTarget.y <= window->WindowPadding.y) - window->ScrollTarget.y = 0.0f; - else if (center_y_ratio >= 1.0f && window->ScrollTarget.y >= window->SizeContents.y - window->WindowPadding.y + GImGui->Style.ItemSpacing.y) - window->ScrollTarget.y = window->SizeContents.y; } // center_y_ratio: 0.0f top of last item, 0.5f vertical center of last item, 1.0f bottom of last item. @@ -7942,10 +8028,10 @@ void ImGui::LogFinish() fclose(g.LogFile); g.LogFile = NULL; } - if (g.LogClipboard->size() > 1) + if (g.LogClipboard.size() > 1) { - SetClipboardText(g.LogClipboard->begin()); - g.LogClipboard->clear(); + SetClipboardText(g.LogClipboard.begin()); + g.LogClipboard.clear(); } g.LogEnabled = false; } @@ -7980,7 +8066,7 @@ bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags) if (flags & ImGuiTreeNodeFlags_Leaf) return true; - // We only write to the tree storage if the user clicks (or explicitely use SetNextTreeNode*** functions) + // We only write to the tree storage if the user clicks (or explicitly use SetNextTreeNode*** functions) ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; ImGuiStorage* storage = window->DC.StateStorage; @@ -8410,73 +8496,83 @@ void ImGui::BulletText(const char* fmt, ...) va_end(args); } -static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, const char* display_format, char* buf, int buf_size) -{ - if (data_type == ImGuiDataType_Int) - ImFormatString(buf, buf_size, display_format, *(int*)data_ptr); - else if (data_type == ImGuiDataType_Float) - ImFormatString(buf, buf_size, display_format, *(float*)data_ptr); - else if (data_type == ImGuiDataType_Double) - ImFormatString(buf, buf_size, display_format, *(double*)data_ptr); -} - -static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, int decimal_precision, char* buf, int buf_size) +static inline int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* data_ptr, const char* format) { - if (data_type == ImGuiDataType_Int) - { - if (decimal_precision < 0) - ImFormatString(buf, buf_size, "%d", *(int*)data_ptr); - else - ImFormatString(buf, buf_size, "%.*d", decimal_precision, *(int*)data_ptr); - } - else if (data_type == ImGuiDataType_Float) - { - if (decimal_precision < 0) - ImFormatString(buf, buf_size, "%f", *(float*)data_ptr); // Ideally we'd have a minimum decimal precision of 1 to visually denote that it is a float, while hiding non-significant digits? - else - ImFormatString(buf, buf_size, "%.*f", decimal_precision, *(float*)data_ptr); - } - else if (data_type == ImGuiDataType_Double) - { - if (decimal_precision < 0) - ImFormatString(buf, buf_size, "%f", *(double*)data_ptr); - else - ImFormatString(buf, buf_size, "%.*f", decimal_precision, *(double*)data_ptr); - } + if (data_type == ImGuiDataType_S32 || data_type == ImGuiDataType_U32) // Signedness doesn't matter when pushing the argument + return ImFormatString(buf, buf_size, format, *(const ImU32*)data_ptr); + if (data_type == ImGuiDataType_S64 || data_type == ImGuiDataType_U64) // Signedness doesn't matter when pushing the argument + return ImFormatString(buf, buf_size, format, *(const ImU64*)data_ptr); + if (data_type == ImGuiDataType_Float) + return ImFormatString(buf, buf_size, format, *(const float*)data_ptr); + if (data_type == ImGuiDataType_Double) + return ImFormatString(buf, buf_size, format, *(const double*)data_ptr); + IM_ASSERT(0); + return 0; } +// FIXME: Adding support for clamping on boundaries of the data type would be nice. static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, void* arg1, const void* arg2) { IM_ASSERT(op == '+' || op == '-'); - if (data_type == ImGuiDataType_Int) - { - if (op == '+') *(int*)output = *(int*)arg1 + *(const int*)arg2; - else if (op == '-') *(int*)output = *(int*)arg1 - *(const int*)arg2; - } - else if (data_type == ImGuiDataType_Float) + switch (data_type) { - if (op == '+') *(float*)output = *(float*)arg1 + *(const float*)arg2; - else if (op == '-') *(float*)output = *(float*)arg1 - *(const float*)arg2; - } - else if (data_type == ImGuiDataType_Double) - { - if (op == '+') *(double*)output = *(double*)arg1 + *(const double*)arg2; - else if (op == '-') *(double*)output = *(double*)arg1 - *(const double*)arg2; + case ImGuiDataType_S32: + if (op == '+') *(int*)output = *(const int*)arg1 + *(const int*)arg2; + else if (op == '-') *(int*)output = *(const int*)arg1 - *(const int*)arg2; + return; + case ImGuiDataType_U32: + if (op == '+') *(unsigned int*)output = *(const unsigned int*)arg1 + *(const ImU32*)arg2; + else if (op == '-') *(unsigned int*)output = *(const unsigned int*)arg1 - *(const ImU32*)arg2; + return; + case ImGuiDataType_S64: + if (op == '+') *(ImS64*)output = *(const ImS64*)arg1 + *(const ImS64*)arg2; + else if (op == '-') *(ImS64*)output = *(const ImS64*)arg1 - *(const ImS64*)arg2; + return; + case ImGuiDataType_U64: + if (op == '+') *(ImU64*)output = *(const ImU64*)arg1 + *(const ImU64*)arg2; + else if (op == '-') *(ImU64*)output = *(const ImU64*)arg1 - *(const ImU64*)arg2; + return; + case ImGuiDataType_Float: + if (op == '+') *(float*)output = *(const float*)arg1 + *(const float*)arg2; + else if (op == '-') *(float*)output = *(const float*)arg1 - *(const float*)arg2; + return; + case ImGuiDataType_Double: + if (op == '+') *(double*)output = *(const double*)arg1 + *(const double*)arg2; + else if (op == '-') *(double*)output = *(const double*)arg1 - *(const double*)arg2; + return; + case ImGuiDataType_COUNT: break; } + IM_ASSERT(0); } -static size_t GDataTypeSize[ImGuiDataType_COUNT] = +struct ImGuiDataTypeInfo { - sizeof(int), - sizeof(float), - sizeof(double) + size_t Size; + const char* PrintFmt; // Unused + const char* ScanFmt; }; +static const ImGuiDataTypeInfo GDataTypeInfo[] = +{ + { sizeof(int), "%d", "%d" }, + { sizeof(unsigned int), "%u", "%u" }, +#ifdef _MSC_VER + { sizeof(ImS64), "%I64d","%I64d" }, + { sizeof(ImU64), "%I64u","%I64u" }, +#else + { sizeof(ImS64), "%lld", "%lld" }, + { sizeof(ImU64), "%llu", "%llu" }, +#endif + { sizeof(float), "%f", "%f" }, // float are promoted to double in va_arg + { sizeof(double), "%f", "%lf" }, +}; +IM_STATIC_ASSERT(IM_ARRAYSIZE(GDataTypeInfo) == ImGuiDataType_COUNT); + // User can input math operators (e.g. +100) to edit a numerical values. -// NB: This is _not_ a full expression evaluator. We should probably add one though.. -static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* scalar_format) +// NB: This is _not_ a full expression evaluator. We should probably add one and replace this dumb mess.. +static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* format) { - while (ImCharIsSpace((unsigned int)*buf)) + while (ImCharIsBlankA(*buf)) buf++; // We don't support '-' op because it would conflict with inputing negative value. @@ -8485,7 +8581,7 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b if (op == '+' || op == '*' || op == '/') { buf++; - while (ImCharIsSpace((unsigned int)*buf)) + while (ImCharIsBlankA(*buf)) buf++; } else @@ -8495,35 +8591,44 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b if (!buf[0]) return false; + // Copy the value in an opaque buffer so we can compare at the end of the function if it changed at all. IM_ASSERT(data_type < ImGuiDataType_COUNT); int data_backup[2]; - IM_ASSERT(GDataTypeSize[data_type] <= sizeof(data_backup)); - memcpy(data_backup, data_ptr, GDataTypeSize[data_type]); + IM_ASSERT(GDataTypeInfo[data_type].Size <= sizeof(data_backup)); + memcpy(data_backup, data_ptr, GDataTypeInfo[data_type].Size); - if (data_type == ImGuiDataType_Int) + if (format == NULL) + format = GDataTypeInfo[data_type].ScanFmt; + + int arg1i = 0; + if (data_type == ImGuiDataType_S32) { - if (!scalar_format) - scalar_format = "%d"; int* v = (int*)data_ptr; int arg0i = *v; - if (op && sscanf(initial_value_buf, scalar_format, &arg0i) < 1) + float arg1f = 0.0f; + if (op && sscanf(initial_value_buf, format, &arg0i) < 1) return false; // Store operand in a float so we can use fractional value for multipliers (*1.1), but constant always parsed as integer so we can fit big integers (e.g. 2000000003) past float precision - float arg1f = 0.0f; - if (op == '+') { if (sscanf(buf, "%f", &arg1f) == 1) *v = (int)(arg0i + arg1f); } // Add (use "+-" to subtract) - else if (op == '*') { if (sscanf(buf, "%f", &arg1f) == 1) *v = (int)(arg0i * arg1f); } // Multiply - else if (op == '/') { if (sscanf(buf, "%f", &arg1f) == 1 && arg1f != 0.0f) *v = (int)(arg0i / arg1f); }// Divide - else { if (sscanf(buf, scalar_format, &arg0i) == 1) *v = arg0i; } // Assign integer constant + if (op == '+') { if (sscanf(buf, "%d", &arg1i)) *v = (int)(arg0i + arg1i); } // Add (use "+-" to subtract) + else if (op == '*') { if (sscanf(buf, "%f", &arg1f)) *v = (int)(arg0i * arg1f); } // Multiply + else if (op == '/') { if (sscanf(buf, "%f", &arg1f) && arg1f != 0.0f) *v = (int)(arg0i / arg1f); } // Divide + else { if (sscanf(buf, format, &arg1i) == 1) *v = arg1i; } // Assign constant + } + else if (data_type == ImGuiDataType_U32 || data_type == ImGuiDataType_S64 || data_type == ImGuiDataType_U64) + { + // Assign constant + // FIXME: We don't bother handling support for legacy operators since they are a little too crappy. Instead we may implement a proper expression evaluator in the future. + sscanf(buf, format, data_ptr); } else if (data_type == ImGuiDataType_Float) { // For floats we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in - scalar_format = "%f"; + format = "%f"; float* v = (float*)data_ptr; float arg0f = *v, arg1f = 0.0f; - if (op && sscanf(initial_value_buf, scalar_format, &arg0f) < 1) + if (op && sscanf(initial_value_buf, format, &arg0f) < 1) return false; - if (sscanf(buf, scalar_format, &arg1f) < 1) + if (sscanf(buf, format, &arg1f) < 1) return false; if (op == '+') { *v = arg0f + arg1f; } // Add (use "+-" to subtract) else if (op == '*') { *v = arg0f * arg1f; } // Multiply @@ -8532,24 +8637,24 @@ static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_b } else if (data_type == ImGuiDataType_Double) { - scalar_format = "%lf"; + format = "%lf"; // scanf differentiate float/double unlike printf which forces everything to double because of ellipsis double* v = (double*)data_ptr; - double arg0f = *v, arg1f = 0.0f; - if (op && sscanf(initial_value_buf, scalar_format, &arg0f) < 1) + double arg0f = *v, arg1f = 0.0; + if (op && sscanf(initial_value_buf, format, &arg0f) < 1) return false; - if (sscanf(buf, scalar_format, &arg1f) < 1) + if (sscanf(buf, format, &arg1f) < 1) return false; if (op == '+') { *v = arg0f + arg1f; } // Add (use "+-" to subtract) else if (op == '*') { *v = arg0f * arg1f; } // Multiply else if (op == '/') { if (arg1f != 0.0f) *v = arg0f / arg1f; } // Divide else { *v = arg1f; } // Assign constant } - return memcmp(data_backup, data_ptr, GDataTypeSize[data_type]) != 0; + return memcmp(data_backup, data_ptr, GDataTypeInfo[data_type].Size) != 0; } // Create text input in place of a slider (when CTRL+Clicking on slider) // FIXME: Logic is messy and confusing. -bool ImGui::InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision) +bool ImGui::InputScalarAsWidgetReplacement(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* data_ptr, const char* format) { ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); @@ -8561,93 +8666,151 @@ bool ImGui::InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label SetHoveredID(0); FocusableItemUnregister(window); - char buf[32]; - DataTypeFormatString(data_type, data_ptr, decimal_precision, buf, IM_ARRAYSIZE(buf)); - bool text_value_changed = InputTextEx(label, buf, IM_ARRAYSIZE(buf), aabb.GetSize(), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll); + char fmt_buf[32]; + char data_buf[32]; + format = ImParseFormatTrimDecorations(format, fmt_buf, IM_ARRAYSIZE(fmt_buf)); + DataTypeFormatString(data_buf, IM_ARRAYSIZE(data_buf), data_type, data_ptr, format); + ImStrTrimBlanks(data_buf); + ImGuiInputTextFlags flags = ImGuiInputTextFlags_AutoSelectAll | ((data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) ? ImGuiInputTextFlags_CharsScientific : ImGuiInputTextFlags_CharsDecimal); + bool value_changed = InputTextEx(label, data_buf, IM_ARRAYSIZE(data_buf), bb.GetSize(), flags); if (g.ScalarAsInputTextId == 0) // First frame we started displaying the InputText widget { - IM_ASSERT(g.ActiveId == id); // InputText ID expected to match the Slider ID (else we'd need to store them both, which is also possible) + IM_ASSERT(g.ActiveId == id); // InputText ID expected to match the Slider ID g.ScalarAsInputTextId = g.ActiveId; SetHoveredID(id); } - if (text_value_changed) - return DataTypeApplyOpFromText(buf, GImGui->InputTextState.InitialText.begin(), data_type, data_ptr, NULL); + if (value_changed) + return DataTypeApplyOpFromText(data_buf, g.InputTextState.InitialText.begin(), data_type, data_ptr, NULL); return false; } -// Parse display precision back from the display format string -int ImGui::ParseFormatPrecision(const char* fmt, int default_precision) +// We don't use strchr() because our strings are usually very short and often start with '%' +const char* ImParseFormatFindStart(const char* fmt) { - int precision = default_precision; - while ((fmt = strchr(fmt, '%')) != NULL) + while (char c = fmt[0]) { - fmt++; - if (fmt[0] == '%') { fmt++; continue; } // Ignore "%%" - while (*fmt >= '0' && *fmt <= '9') + if (c == '%' && fmt[1] != '%') + return fmt; + else if (c == '%') fmt++; - if (*fmt == '.') - { - fmt = ImAtoi(fmt + 1, &precision); - if (precision < 0 || precision > 10) - precision = default_precision; - } - if (*fmt == 'e' || *fmt == 'E') // Maximum precision with scientific notation - precision = -1; - break; + fmt++; } - return precision; + return fmt; } -static float GetMinimumStepAtDecimalPrecision(int decimal_precision) +const char* ImParseFormatFindEnd(const char* fmt) { - static const float min_steps[10] = { 1.0f, 0.1f, 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f, 0.0000001f, 0.00000001f, 0.000000001f }; - return (decimal_precision >= 0 && decimal_precision < 10) ? min_steps[decimal_precision] : powf(10.0f, (float)-decimal_precision); + // Printf/scanf types modifiers: I/L/h/j/l/t/w/z. Other uppercase letters qualify as types aka end of the format. + if (fmt[0] != '%') + return fmt; + const unsigned int ignored_uppercase_mask = (1 << ('I'-'A')) | (1 << ('L'-'A')); + const unsigned int ignored_lowercase_mask = (1 << ('h'-'a')) | (1 << ('j'-'a')) | (1 << ('l'-'a')) | (1 << ('t'-'a')) | (1 << ('w'-'a')) | (1 << ('z'-'a')); + for (char c; (c = *fmt) != 0; fmt++) + { + if (c >= 'A' && c <= 'Z' && ((1 << (c - 'A')) & ignored_uppercase_mask) == 0) + return fmt + 1; + if (c >= 'a' && c <= 'z' && ((1 << (c - 'a')) & ignored_lowercase_mask) == 0) + return fmt + 1; + } + return fmt; +} + +// Extract the format out of a format string with leading or trailing decorations +// fmt = "blah blah" -> return fmt +// fmt = "%.3f" -> return fmt +// fmt = "hello %.3f" -> return fmt + 6 +// fmt = "%.3f hello" -> return buf written with "%.3f" +const char* ImParseFormatTrimDecorations(const char* fmt, char* buf, int buf_size) +{ + const char* fmt_start = ImParseFormatFindStart(fmt); + if (fmt_start[0] != '%') + return fmt; + const char* fmt_end = ImParseFormatFindEnd(fmt_start); + if (fmt_end[0] == 0) // If we only have leading decoration, we don't need to copy the data. + return fmt_start; + ImStrncpy(buf, fmt_start, ImMin((int)(fmt_end + 1 - fmt_start), buf_size)); + return buf; } -float ImGui::RoundScalar(float value, int decimal_precision) +// Parse display precision back from the display format string +// FIXME: This is still used by some navigation code path to infer a minimum tweak step, but we should aim to rework widgets so it isn't needed. +int ImParseFormatPrecision(const char* fmt, int default_precision) +{ + fmt = ImParseFormatFindStart(fmt); + if (fmt[0] != '%') + return default_precision; + fmt++; + while (*fmt >= '0' && *fmt <= '9') + fmt++; + int precision = INT_MAX; + if (*fmt == '.') + { + fmt = ImAtoi(fmt + 1, &precision); + if (precision < 0 || precision > 99) + precision = default_precision; + } + if (*fmt == 'e' || *fmt == 'E') // Maximum precision with scientific notation + precision = -1; + if ((*fmt == 'g' || *fmt == 'G') && precision == INT_MAX) + precision = -1; + return (precision == INT_MAX) ? default_precision : precision; +} + +static float GetMinimumStepAtDecimalPrecision(int decimal_precision) { - // Round past decimal precision - // So when our value is 1.99999 with a precision of 0.001 we'll end up rounding to 2.0 - // FIXME: Investigate better rounding methods + static const float min_steps[10] = { 1.0f, 0.1f, 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f, 0.0000001f, 0.00000001f, 0.000000001f }; if (decimal_precision < 0) - return value; - const float min_step = GetMinimumStepAtDecimalPrecision(decimal_precision); - bool negative = value < 0.0f; - value = fabsf(value); - float remainder = fmodf(value, min_step); - if (remainder <= min_step*0.5f) - value -= remainder; + return FLT_MIN; + return (decimal_precision >= 0 && decimal_precision < 10) ? min_steps[decimal_precision] : ImPow(10.0f, (float)-decimal_precision); +} + +template +static inline TYPE RoundScalarWithFormat(const char* format, ImGuiDataType data_type, TYPE v) +{ + const char* fmt_start = ImParseFormatFindStart(format); + if (fmt_start[0] != '%' || fmt_start[1] == '%') // Don't apply if the value is not visible in the format string + return v; + char v_str[64]; + ImFormatString(v_str, IM_ARRAYSIZE(v_str), fmt_start, v); + const char* p = v_str; + while (*p == ' ') + p++; + if (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) + v = (TYPE)ImAtof(p); else - value += (min_step - remainder); - return negative ? -value : value; + ImAtoi(p, (SIGNEDTYPE*)&v); + return v; } -static inline float SliderBehaviorCalcRatioFromValue(float v, float v_min, float v_max, float power, float linear_zero_pos) +template +static inline float SliderBehaviorCalcRatioFromValue(ImGuiDataType data_type, TYPE v, TYPE v_min, TYPE v_max, float power, float linear_zero_pos) { if (v_min == v_max) return 0.0f; - const bool is_non_linear = (power < 1.0f-0.00001f) || (power > 1.0f+0.00001f); - const float v_clamped = (v_min < v_max) ? ImClamp(v, v_min, v_max) : ImClamp(v, v_max, v_min); - if (is_non_linear) + const bool is_power = (power != 1.0f) && (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double); + const TYPE v_clamped = (v_min < v_max) ? ImClamp(v, v_min, v_max) : ImClamp(v, v_max, v_min); + if (is_power) { if (v_clamped < 0.0f) { - const float f = 1.0f - (v_clamped - v_min) / (ImMin(0.0f,v_max) - v_min); - return (1.0f - powf(f, 1.0f/power)) * linear_zero_pos; + const float f = 1.0f - (float)((v_clamped - v_min) / (ImMin((TYPE)0, v_max) - v_min)); + return (1.0f - ImPow(f, 1.0f/power)) * linear_zero_pos; } else { - const float f = (v_clamped - ImMax(0.0f,v_min)) / (v_max - ImMax(0.0f,v_min)); - return linear_zero_pos + powf(f, 1.0f/power) * (1.0f - linear_zero_pos); + const float f = (float)((v_clamped - ImMax((TYPE)0, v_min)) / (v_max - ImMax((TYPE)0, v_min))); + return linear_zero_pos + ImPow(f, 1.0f/power) * (1.0f - linear_zero_pos); } } // Linear slider - return (v_clamped - v_min) / (v_max - v_min); + return (float)((FLOATTYPE)(v_clamped - v_min) / (FLOATTYPE)(v_max - v_min)); } -bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, ImGuiSliderFlags flags) +// FIXME: Move some of the code into SliderBehavior(). Current responsability is larger than what the equivalent DragBehaviorT<> does, we also do some rendering, etc. +template +static bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, TYPE* v, const TYPE v_min, const TYPE v_max, const char* format, float power, ImGuiSliderFlags flags) { ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); @@ -8655,31 +8818,32 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v // Draw frame const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg); - RenderNavHighlight(frame_bb, id); - RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, style.FrameRounding); + RenderNavHighlight(bb, id); + RenderFrame(bb.Min, bb.Max, frame_col, true, style.FrameRounding); - const bool is_non_linear = (power < 1.0f-0.00001f) || (power > 1.0f+0.00001f); const bool is_horizontal = (flags & ImGuiSliderFlags_Vertical) == 0; + const bool is_decimal = (data_type == ImGuiDataType_Float) || (data_type == ImGuiDataType_Double); + const bool is_power = (power != 1.0f) && is_decimal; const float grab_padding = 2.0f; - const float slider_sz = is_horizontal ? (frame_bb.GetWidth() - grab_padding * 2.0f) : (frame_bb.GetHeight() - grab_padding * 2.0f); - float grab_sz; - if (decimal_precision != 0) - grab_sz = ImMin(style.GrabMinSize, slider_sz); - else - grab_sz = ImMin(ImMax(1.0f * (slider_sz / ((v_min < v_max ? v_max - v_min : v_min - v_max) + 1.0f)), style.GrabMinSize), slider_sz); // Integer sliders, if possible have the grab size represent 1 unit + const float slider_sz = is_horizontal ? (bb.GetWidth() - grab_padding * 2.0f) : (bb.GetHeight() - grab_padding * 2.0f); + float grab_sz = style.GrabMinSize; + SIGNEDTYPE v_range = (v_min < v_max ? v_max - v_min : v_min - v_max); + if (!is_decimal && v_range >= 0) // v_range < 0 may happen on integer overflows + grab_sz = ImMax((float)(slider_sz / (v_range + 1)), style.GrabMinSize); // For integer sliders: if possible have the grab size represent 1 unit + grab_sz = ImMin(grab_sz, slider_sz); const float slider_usable_sz = slider_sz - grab_sz; - const float slider_usable_pos_min = (is_horizontal ? frame_bb.Min.x : frame_bb.Min.y) + grab_padding + grab_sz*0.5f; - const float slider_usable_pos_max = (is_horizontal ? frame_bb.Max.x : frame_bb.Max.y) - grab_padding - grab_sz*0.5f; + const float slider_usable_pos_min = (is_horizontal ? bb.Min.x : bb.Min.y) + grab_padding + grab_sz*0.5f; + const float slider_usable_pos_max = (is_horizontal ? bb.Max.x : bb.Max.y) - grab_padding - grab_sz*0.5f; - // For logarithmic sliders that cross over sign boundary we want the exponential increase to be symmetric around 0.0f - float linear_zero_pos = 0.0f; // 0.0->1.0f - if (v_min * v_max < 0.0f) + // For power curve sliders that cross over sign boundary we want the curve to be symmetric around 0.0f + float linear_zero_pos; // 0.0->1.0f + if (is_power && v_min * v_max < 0.0f) { // Different sign - const float linear_dist_min_to_0 = powf(fabsf(0.0f - v_min), 1.0f/power); - const float linear_dist_max_to_0 = powf(fabsf(v_max - 0.0f), 1.0f/power); - linear_zero_pos = linear_dist_min_to_0 / (linear_dist_min_to_0+linear_dist_max_to_0); + const FLOATTYPE linear_dist_min_to_0 = ImPow(v_min >= 0 ? (FLOATTYPE)v_min : -(FLOATTYPE)v_min, (FLOATTYPE)1.0f/power); + const FLOATTYPE linear_dist_max_to_0 = ImPow(v_max >= 0 ? (FLOATTYPE)v_max : -(FLOATTYPE)v_max, (FLOATTYPE)1.0f/power); + linear_zero_pos = (float)(linear_dist_min_to_0 / (linear_dist_min_to_0 + linear_dist_max_to_0)); } else { @@ -8718,20 +8882,20 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v } else if (delta != 0.0f) { - clicked_t = SliderBehaviorCalcRatioFromValue(*v, v_min, v_max, power, linear_zero_pos); - if (decimal_precision == 0 && !is_non_linear) - { - if (fabsf(v_max - v_min) <= 100.0f || IsNavInputDown(ImGuiNavInput_TweakSlow)) - delta = ((delta < 0.0f) ? -1.0f : +1.0f) / (v_max - v_min); // Gamepad/keyboard tweak speeds in integer steps - else - delta /= 100.0f; - } - else + clicked_t = SliderBehaviorCalcRatioFromValue(data_type, *v, v_min, v_max, power, linear_zero_pos); + if (is_decimal || is_power) { delta /= 100.0f; // Gamepad/keyboard tweak speeds in % of slider bounds if (IsNavInputDown(ImGuiNavInput_TweakSlow)) delta /= 10.0f; } + else + { + if ((v_range >= -100.0f && v_range <= 100.0f) || IsNavInputDown(ImGuiNavInput_TweakSlow)) + delta = ((delta < 0.0f) ? -1.0f : +1.0f) / (float)v_range; // Gamepad/keyboard tweak speeds in integer steps + else + delta /= 100.0f; + } if (IsNavInputDown(ImGuiNavInput_TweakFast)) delta *= 10.0f; set_new_value = true; @@ -8744,66 +8908,133 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v if (set_new_value) { - float new_value; - if (is_non_linear) + TYPE v_new; + if (is_power) { - // Account for logarithmic scale on both sides of the zero + // Account for power curve scale on both sides of the zero if (clicked_t < linear_zero_pos) { // Negative: rescale to the negative range before powering float a = 1.0f - (clicked_t / linear_zero_pos); - a = powf(a, power); - new_value = ImLerp(ImMin(v_max,0.0f), v_min, a); + a = ImPow(a, power); + v_new = ImLerp(ImMin(v_max, (TYPE)0), v_min, a); } else { // Positive: rescale to the positive range before powering float a; - if (fabsf(linear_zero_pos - 1.0f) > 1.e-6f) + if (ImFabs(linear_zero_pos - 1.0f) > 1.e-6f) a = (clicked_t - linear_zero_pos) / (1.0f - linear_zero_pos); else a = clicked_t; - a = powf(a, power); - new_value = ImLerp(ImMax(v_min,0.0f), v_max, a); + a = ImPow(a, power); + v_new = ImLerp(ImMax(v_min, (TYPE)0), v_max, a); } } else { // Linear slider - new_value = ImLerp(v_min, v_max, clicked_t); + if (is_decimal) + { + v_new = ImLerp(v_min, v_max, clicked_t); + } + else + { + // For integer values we want the clicking position to match the grab box so we round above + // This code is carefully tuned to work with large values (e.g. high ranges of U64) while preserving this property.. + FLOATTYPE v_new_off_f = (v_max - v_min) * clicked_t; + TYPE v_new_off_floor = (TYPE)(v_new_off_f); + TYPE v_new_off_round = (TYPE)(v_new_off_f + (FLOATTYPE)0.5); + if (!is_decimal && v_new_off_floor < v_new_off_round) + v_new = v_min + v_new_off_round; + else + v_new = v_min + v_new_off_floor; + } } - // Round past decimal precision - new_value = RoundScalar(new_value, decimal_precision); - if (*v != new_value) + // Round to user desired precision based on format string + v_new = RoundScalarWithFormat(format, data_type, v_new); + + // Apply result + if (*v != v_new) { - *v = new_value; + *v = v_new; value_changed = true; } } } // Draw - float grab_t = SliderBehaviorCalcRatioFromValue(*v, v_min, v_max, power, linear_zero_pos); + float grab_t = SliderBehaviorCalcRatioFromValue(data_type, *v, v_min, v_max, power, linear_zero_pos); if (!is_horizontal) grab_t = 1.0f - grab_t; const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t); ImRect grab_bb; if (is_horizontal) - grab_bb = ImRect(ImVec2(grab_pos - grab_sz*0.5f, frame_bb.Min.y + grab_padding), ImVec2(grab_pos + grab_sz*0.5f, frame_bb.Max.y - grab_padding)); + grab_bb = ImRect(grab_pos - grab_sz*0.5f, bb.Min.y + grab_padding, grab_pos + grab_sz*0.5f, bb.Max.y - grab_padding); else - grab_bb = ImRect(ImVec2(frame_bb.Min.x + grab_padding, grab_pos - grab_sz*0.5f), ImVec2(frame_bb.Max.x - grab_padding, grab_pos + grab_sz*0.5f)); + grab_bb = ImRect(bb.Min.x + grab_padding, grab_pos - grab_sz*0.5f, bb.Max.x - grab_padding, grab_pos + grab_sz*0.5f); window->DrawList->AddRectFilled(grab_bb.Min, grab_bb.Max, GetColorU32(g.ActiveId == id ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding); return value_changed; } -// Use power!=1.0 for logarithmic sliders. -// Adjust display_format to decorate the value with a prefix or a suffix. -// "%.3f" 1.234 -// "%5.2f secs" 01.23 secs -// "Gold: %.0f" Gold: 1 -bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format, float power) +// For 32-bits and larger types, slider bounds are limited to half the natural type range. +// So e.g. an integer Slider between INT_MAX-10 and INT_MAX will fail, but an integer Slider between INT_MAX/2-10 and INT_MAX/2. +// It would be possible to life that limitation with some work but it doesn't seem to be work it for sliders. +bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* v, const void* v_min, const void* v_max, const char* format, float power, ImGuiSliderFlags flags) +{ + switch (data_type) + { + case ImGuiDataType_S32: + IM_ASSERT(*(const ImS32*)v_min >= IM_S32_MIN/2 && *(const ImS32*)v_max <= IM_S32_MAX/2); + return SliderBehaviorT(bb, id, data_type, (ImS32*)v, *(const ImS32*)v_min, *(const ImS32*)v_max, format, power, flags); + case ImGuiDataType_U32: + IM_ASSERT(*(const ImU32*)v_min <= IM_U32_MAX/2); + return SliderBehaviorT(bb, id, data_type, (ImU32*)v, *(const ImU32*)v_min, *(const ImU32*)v_max, format, power, flags); + case ImGuiDataType_S64: + IM_ASSERT(*(const ImS64*)v_min >= IM_S64_MIN/2 && *(const ImS64*)v_max <= IM_S64_MAX/2); + return SliderBehaviorT(bb, id, data_type, (ImS64*)v, *(const ImS64*)v_min, *(const ImS64*)v_max, format, power, flags); + case ImGuiDataType_U64: + IM_ASSERT(*(const ImU64*)v_min <= IM_U64_MAX/2); + return SliderBehaviorT(bb, id, data_type, (ImU64*)v, *(const ImU64*)v_min, *(const ImU64*)v_max, format, power, flags); + case ImGuiDataType_Float: + IM_ASSERT(*(const float*)v_min >= -FLT_MAX/2.0f && *(const float*)v_max <= FLT_MAX/2.0f); + return SliderBehaviorT(bb, id, data_type, (float*)v, *(const float*)v_min, *(const float*)v_max, format, power, flags); + case ImGuiDataType_Double: + IM_ASSERT(*(const double*)v_min >= -DBL_MAX/2.0f && *(const double*)v_max <= DBL_MAX/2.0f); + return SliderBehaviorT(bb, id, data_type, (double*)v, *(const double*)v_min, *(const double*)v_max, format, power, flags); + case ImGuiDataType_COUNT: break; + } + IM_ASSERT(0); + return false; +} + +// FIXME-LEGACY: Prior to 1.61 our DragInt() function internally used floats and because of this the compile-time default value for format was "%.0f". +// Even though we changed the compile-time default, we expect users to have carried %f around, which would break the display of DragInt() calls. +// To honor backward compatibility we are rewriting the format string, unless IMGUI_DISABLE_OBSOLETE_FUNCTIONS is enabled. What could possibly go wrong?! +static const char* PatchFormatStringFloatToInt(const char* fmt) +{ + if (fmt[0] == '%' && fmt[1] == '.' && fmt[2] == '0' && fmt[3] == 'f' && fmt[4] == 0) // Fast legacy path for "%.0f" which is expected to be the most common case. + return "%d"; + const char* fmt_start = ImParseFormatFindStart(fmt); // Find % (if any, and ignore %%) + const char* fmt_end = ImParseFormatFindEnd(fmt_start); // Find end of format specifier, which itself is an exercise of confidence/recklessness (because snprintf is dependent on libc or user). + if (fmt_end > fmt_start && fmt_end[-1] == 'f') + { +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + if (fmt_start == fmt && fmt_end[0] == 0) + return "%d"; + ImGuiContext& g = *GImGui; + ImFormatString(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), "%.*s%%d%s", (int)(fmt_start - fmt), fmt, fmt_end); // Honor leading and trailing decorations, but lose alignment/precision. + return g.TempBuffer; +#else + IM_ASSERT(0 && "DragInt(): Invalid format string!"); // Old versions used a default parameter of "%.0f", please replace with e.g. "%d" +#endif + } + return fmt; +} + +bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* v, const void* v_min, const void* v_max, const char* format, float power) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) @@ -8824,15 +9055,19 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c ItemSize(total_bb, style.FramePadding.y); return false; } - const bool hovered = ItemHoverable(frame_bb, id); - if (!display_format) - display_format = "%.3f"; - int decimal_precision = ParseFormatPrecision(display_format, 3); + // Default format string when passing NULL + // Patch old "%.0f" format string to use "%d", read function comments for more details. + IM_ASSERT(data_type >= 0 && data_type < ImGuiDataType_COUNT); + if (format == NULL) + format = GDataTypeInfo[data_type].PrintFmt; + else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0) + format = PatchFormatStringFloatToInt(format); // Tabbing or CTRL-clicking on Slider turns it into an input box bool start_text_input = false; const bool tab_focus_requested = FocusableItemRegister(window, id); + const bool hovered = ItemHoverable(frame_bb, id); if (tab_focus_requested || (hovered && g.IO.MouseClicked[0]) || g.NavActivateId == id || (g.NavInputId == id && g.ScalarAsInputTextId != id)) { SetActiveID(id, window); @@ -8846,15 +9081,15 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c } } if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id)) - return InputScalarAsWidgetReplacement(frame_bb, label, ImGuiDataType_Float, v, id, decimal_precision); + return InputScalarAsWidgetReplacement(frame_bb, id, label, data_type, v, format); // Actual slider behavior + render grab ItemSize(total_bb, style.FramePadding.y); - const bool value_changed = SliderBehavior(frame_bb, id, v, v_min, v_max, power, decimal_precision); + const bool value_changed = SliderBehavior(frame_bb, id, data_type, v, v_min, v_max, format, power); // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. char value_buf[64]; - const char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); + const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, v, format); RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f,0.5f)); if (label_size.x > 0.0f) @@ -8863,7 +9098,12 @@ bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, c return value_changed; } -bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* display_format, float power) +bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, const char* format, float power) +{ + return SliderScalar(label, ImGuiDataType_Float, v, &v_min, &v_max, format, power); +} + +bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType data_type, void* v, const void* v_min, const void* v_max, const char* format, float power) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) @@ -8880,12 +9120,16 @@ bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float ItemSize(bb, style.FramePadding.y); if (!ItemAdd(frame_bb, id)) return false; - const bool hovered = ItemHoverable(frame_bb, id); - if (!display_format) - display_format = "%.3f"; - int decimal_precision = ParseFormatPrecision(display_format, 3); + // Default format string when passing NULL + // Patch old "%.0f" format string to use "%d", read function comments for more details. + IM_ASSERT(data_type >= 0 && data_type < ImGuiDataType_COUNT); + if (format == NULL) + format = GDataTypeInfo[data_type].PrintFmt; + else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0) + format = PatchFormatStringFloatToInt(format); + const bool hovered = ItemHoverable(frame_bb, id); if ((hovered && g.IO.MouseClicked[0]) || g.NavActivateId == id || g.NavInputId == id) { SetActiveID(id, window); @@ -8895,12 +9139,12 @@ bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float } // Actual slider behavior + render grab - bool value_changed = SliderBehavior(frame_bb, id, v, v_min, v_max, power, decimal_precision, ImGuiSliderFlags_Vertical); + bool value_changed = SliderBehavior(frame_bb, id, data_type, v, v_min, v_max, format, power, ImGuiSliderFlags_Vertical); // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. // For the vertical slider we allow centered text to overlap the frame padding char value_buf[64]; - char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); + const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, v, format); RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f,0.0f)); if (label_size.x > 0.0f) RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); @@ -8916,28 +9160,23 @@ bool ImGui::SliderAngle(const char* label, float* v_rad, float v_degrees_min, fl return value_changed; } -bool ImGui::SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format) +bool ImGui::SliderInt(const char* label, int* v, int v_min, int v_max, const char* format) { - if (!display_format) - display_format = "%.0f"; - float v_f = (float)*v; - bool value_changed = SliderFloat(label, &v_f, (float)v_min, (float)v_max, display_format, 1.0f); - *v = (int)v_f; - return value_changed; + return SliderScalar(label, ImGuiDataType_S32, v, &v_min, &v_max, format); } -bool ImGui::VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format) +bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* format, float power) { - if (!display_format) - display_format = "%.0f"; - float v_f = (float)*v; - bool value_changed = VSliderFloat(label, size, &v_f, (float)v_min, (float)v_max, display_format, 1.0f); - *v = (int)v_f; - return value_changed; + return VSliderScalar(label, size, ImGuiDataType_Float, v, &v_min, &v_max, format, power); +} + +bool ImGui::VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* format) +{ + return VSliderScalar(label, size, ImGuiDataType_S32, v, &v_min, &v_max, format); } // Add multiple sliders on 1 line for compact edition of multiple components -bool ImGui::SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* display_format, float power) +bool ImGui::SliderScalarN(const char* label, ImGuiDataType data_type, void* v, int components, const void* v_min, const void* v_max, const char* format, float power) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) @@ -8948,173 +9187,188 @@ bool ImGui::SliderFloatN(const char* label, float* v, int components, float v_mi BeginGroup(); PushID(label); PushMultiItemsWidths(components); + size_t type_size = GDataTypeInfo[data_type].Size; for (int i = 0; i < components; i++) { PushID(i); - value_changed |= SliderFloat("##v", &v[i], v_min, v_max, display_format, power); + value_changed |= SliderScalar("##v", data_type, v, v_min, v_max, format, power); SameLine(0, g.Style.ItemInnerSpacing.x); PopID(); PopItemWidth(); + v = (void*)((char*)v + type_size); } PopID(); TextUnformatted(label, FindRenderedTextEnd(label)); EndGroup(); - return value_changed; } -bool ImGui::SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format, float power) +bool ImGui::SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* format, float power) { - return SliderFloatN(label, v, 2, v_min, v_max, display_format, power); + return SliderScalarN(label, ImGuiDataType_Float, v, 2, &v_min, &v_max, format, power); } -bool ImGui::SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format, float power) +bool ImGui::SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* format, float power) { - return SliderFloatN(label, v, 3, v_min, v_max, display_format, power); + return SliderScalarN(label, ImGuiDataType_Float, v, 3, &v_min, &v_max, format, power); } -bool ImGui::SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* display_format, float power) +bool ImGui::SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* format, float power) { - return SliderFloatN(label, v, 4, v_min, v_max, display_format, power); -} - -bool ImGui::SliderIntN(const char* label, int* v, int components, int v_min, int v_max, const char* display_format) -{ - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - ImGuiContext& g = *GImGui; - bool value_changed = false; - BeginGroup(); - PushID(label); - PushMultiItemsWidths(components); - for (int i = 0; i < components; i++) - { - PushID(i); - value_changed |= SliderInt("##v", &v[i], v_min, v_max, display_format); - SameLine(0, g.Style.ItemInnerSpacing.x); - PopID(); - PopItemWidth(); - } - PopID(); - - TextUnformatted(label, FindRenderedTextEnd(label)); - EndGroup(); - - return value_changed; + return SliderScalarN(label, ImGuiDataType_Float, v, 4, &v_min, &v_max, format, power); } -bool ImGui::SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* display_format) +bool ImGui::SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* format) { - return SliderIntN(label, v, 2, v_min, v_max, display_format); + return SliderScalarN(label, ImGuiDataType_S32, v, 2, &v_min, &v_max, format); } -bool ImGui::SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* display_format) +bool ImGui::SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* format) { - return SliderIntN(label, v, 3, v_min, v_max, display_format); + return SliderScalarN(label, ImGuiDataType_S32, v, 3, &v_min, &v_max, format); } -bool ImGui::SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* display_format) +bool ImGui::SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* format) { - return SliderIntN(label, v, 4, v_min, v_max, display_format); + return SliderScalarN(label, ImGuiDataType_S32, v, 4, &v_min, &v_max, format); } -bool ImGui::DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_speed, float v_min, float v_max, int decimal_precision, float power) +// This is called by DragBehavior() when the widget is active (held by mouse or being manipulated with Nav controls) +template +static bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const TYPE v_min, const TYPE v_max, const char* format, float power) { ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; - // Draw frame - const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg); - RenderNavHighlight(frame_bb, id); - RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, style.FrameRounding); + // Default tweak speed + bool has_min_max = (v_min != v_max) && (v_max - v_max < FLT_MAX); + if (v_speed == 0.0f && has_min_max) + v_speed = (float)((v_max - v_min) * g.DragSpeedDefaultRatio); - bool value_changed = false; + // Inputs accumulates into g.DragCurrentAccum, which is flushed into the current value as soon as it makes a difference with our precision settings + float adjust_delta = 0.0f; + if (g.ActiveIdSource == ImGuiInputSource_Mouse && IsMousePosValid() && g.IO.MouseDragMaxDistanceSqr[0] > 1.0f*1.0f) + { + adjust_delta = g.IO.MouseDelta.x; + if (g.IO.KeyAlt) + adjust_delta *= 1.0f/100.0f; + if (g.IO.KeyShift) + adjust_delta *= 10.0f; + } + if (g.ActiveIdSource == ImGuiInputSource_Nav) + { + int decimal_precision = (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) ? ImParseFormatPrecision(format, 3) : 0; + adjust_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard|ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 1.0f/10.0f, 10.0f).x; + v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision)); + } + adjust_delta *= v_speed; - // Process interacting with the drag - if (g.ActiveId == id) + // Clear current value on activation + // Avoid altering values and clamping when we are _already_ past the limits and heading in the same direction, so e.g. if range is 0..255, current value is 300 and we are pushing to the right side, keep the 300. + bool is_just_activated = g.ActiveIdIsJustActivated; + bool is_already_past_limits_and_pushing_outward = has_min_max && ((*v >= v_max && adjust_delta > 0.0f) || (*v <= v_min && adjust_delta < 0.0f)); + if (is_just_activated || is_already_past_limits_and_pushing_outward) { - if (g.ActiveIdSource == ImGuiInputSource_Mouse && !g.IO.MouseDown[0]) - ClearActiveID(); - else if (g.ActiveIdSource == ImGuiInputSource_Nav && g.NavActivatePressedId == id && !g.ActiveIdIsJustActivated) - ClearActiveID(); + g.DragCurrentAccum = 0.0f; + g.DragCurrentAccumDirty = false; } - if (g.ActiveId == id) + else if (adjust_delta != 0.0f) { - if (g.ActiveIdIsJustActivated) - { - // Lock current value on click - g.DragCurrentValue = *v; - g.DragLastMouseDelta = ImVec2(0.f, 0.f); - } + g.DragCurrentAccum += adjust_delta; + g.DragCurrentAccumDirty = true; + } - if (v_speed == 0.0f && (v_max - v_min) != 0.0f && (v_max - v_min) < FLT_MAX) - v_speed = (v_max - v_min) * g.DragSpeedDefaultRatio; + if (!g.DragCurrentAccumDirty) + return false; - float v_cur = g.DragCurrentValue; - const ImVec2 mouse_drag_delta = GetMouseDragDelta(0, 1.0f); - float adjust_delta = 0.0f; - if (g.ActiveIdSource == ImGuiInputSource_Mouse && IsMousePosValid()) - { - adjust_delta = mouse_drag_delta.x - g.DragLastMouseDelta.x; - if (g.IO.KeyShift && g.DragSpeedScaleFast >= 0.0f) - adjust_delta *= g.DragSpeedScaleFast; - if (g.IO.KeyAlt && g.DragSpeedScaleSlow >= 0.0f) - adjust_delta *= g.DragSpeedScaleSlow; - g.DragLastMouseDelta.x = mouse_drag_delta.x; - } - if (g.ActiveIdSource == ImGuiInputSource_Nav) - { - adjust_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard|ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 1.0f/10.0f, 10.0f).x; - if (v_min < v_max && ((v_cur >= v_max && adjust_delta > 0.0f) || (v_cur <= v_min && adjust_delta < 0.0f))) // This is to avoid applying the saturation when already past the limits - adjust_delta = 0.0f; - v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision)); - } - adjust_delta *= v_speed; + TYPE v_cur = *v; + FLOATTYPE v_old_ref_for_accum_remainder = (FLOATTYPE)0.0f; - if (fabsf(adjust_delta) > 0.0f) - { - if (fabsf(power - 1.0f) > 0.001f) - { - // Logarithmic curve on both side of 0.0 - float v0_abs = v_cur >= 0.0f ? v_cur : -v_cur; - float v0_sign = v_cur >= 0.0f ? 1.0f : -1.0f; - float v1 = powf(v0_abs, 1.0f / power) + (adjust_delta * v0_sign); - float v1_abs = v1 >= 0.0f ? v1 : -v1; - float v1_sign = v1 >= 0.0f ? 1.0f : -1.0f; // Crossed sign line - v_cur = powf(v1_abs, power) * v0_sign * v1_sign; // Reapply sign - } - else - { - v_cur += adjust_delta; - } + const bool is_power = (power != 1.0f && (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) && has_min_max); + if (is_power) + { + // Offset + round to user desired precision, with a curve on the v_min..v_max range to get more precision on one side of the range + FLOATTYPE v_old_norm_curved = ImPow((FLOATTYPE)(v_cur - v_min) / (FLOATTYPE)(v_max - v_min), (FLOATTYPE)1.0f / power); + FLOATTYPE v_new_norm_curved = v_old_norm_curved + (g.DragCurrentAccum / (v_max - v_min)); + v_cur = v_min + (TYPE)ImPow(ImSaturate((float)v_new_norm_curved), power) * (v_max - v_min); + v_old_ref_for_accum_remainder = v_old_norm_curved; + } + else + { + v_cur += (TYPE)g.DragCurrentAccum; + } - // Clamp - if (v_min < v_max) - v_cur = ImClamp(v_cur, v_min, v_max); - g.DragCurrentValue = v_cur; - } + // Round to user desired precision based on format string + v_cur = RoundScalarWithFormat(format, data_type, v_cur); - // Round to user desired precision, then apply - v_cur = RoundScalar(v_cur, decimal_precision); - if (*v != v_cur) - { - *v = v_cur; - value_changed = true; - } + // Preserve remainder after rounding has been applied. This also allow slow tweaking of values. + g.DragCurrentAccumDirty = false; + if (is_power) + { + FLOATTYPE v_cur_norm_curved = ImPow((FLOATTYPE)(v_cur - v_min) / (FLOATTYPE)(v_max - v_min), (FLOATTYPE)1.0f / power); + g.DragCurrentAccum -= (float)(v_cur_norm_curved - v_old_ref_for_accum_remainder); + } + else + { + g.DragCurrentAccum -= (float)((SIGNEDTYPE)v_cur - (SIGNEDTYPE)*v); } + + // Lose zero sign for float/double + if (v_cur == (TYPE)-0) + v_cur = (TYPE)0; - return value_changed; + // Clamp values (handle overflow/wrap-around) + if (*v != v_cur && has_min_max) + { + if (v_cur < v_min || (v_cur > *v && adjust_delta < 0.0f)) + v_cur = v_min; + if (v_cur > v_max || (v_cur < *v && adjust_delta > 0.0f)) + v_cur = v_max; + } + + // Apply result + if (*v == v_cur) + return false; + *v = v_cur; + return true; +} + +bool ImGui::DragBehavior(ImGuiID id, ImGuiDataType data_type, void* v, float v_speed, const void* v_min, const void* v_max, const char* format, float power) +{ + ImGuiContext& g = *GImGui; + if (g.ActiveId == id) + { + if (g.ActiveIdSource == ImGuiInputSource_Mouse && !g.IO.MouseDown[0]) + ClearActiveID(); + else if (g.ActiveIdSource == ImGuiInputSource_Nav && g.NavActivatePressedId == id && !g.ActiveIdIsJustActivated) + ClearActiveID(); + } + if (g.ActiveId != id) + return false; + + switch (data_type) + { + case ImGuiDataType_S32: return DragBehaviorT(data_type, (ImS32*)v, v_speed, v_min ? *(const ImS32* )v_min : IM_S32_MIN, v_max ? *(const ImS32* )v_max : IM_S32_MAX, format, power); + case ImGuiDataType_U32: return DragBehaviorT(data_type, (ImU32*)v, v_speed, v_min ? *(const ImU32* )v_min : IM_U32_MIN, v_max ? *(const ImU32* )v_max : IM_U32_MAX, format, power); + case ImGuiDataType_S64: return DragBehaviorT(data_type, (ImS64*)v, v_speed, v_min ? *(const ImS64* )v_min : IM_S64_MIN, v_max ? *(const ImS64* )v_max : IM_S64_MAX, format, power); + case ImGuiDataType_U64: return DragBehaviorT(data_type, (ImU64*)v, v_speed, v_min ? *(const ImU64* )v_min : IM_U64_MIN, v_max ? *(const ImU64* )v_max : IM_U64_MAX, format, power); + case ImGuiDataType_Float: return DragBehaviorT(data_type, (float*)v, v_speed, v_min ? *(const float* )v_min : -FLT_MAX, v_max ? *(const float* )v_max : FLT_MAX, format, power); + case ImGuiDataType_Double: return DragBehaviorT(data_type, (double*)v, v_speed, v_min ? *(const double*)v_min : -DBL_MAX, v_max ? *(const double*)v_max : DBL_MAX, format, power); + case ImGuiDataType_COUNT: break; + } + IM_ASSERT(0); + return false; } -bool ImGui::DragFloat(const char* label, float* v, float v_speed, float v_min, float v_max, const char* display_format, float power) +bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* v, float v_speed, const void* v_min, const void* v_max, const char* format, float power) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) return false; + if (power != 1.0f) + IM_ASSERT(v_min != NULL && v_max != NULL); // When using a power curve the drag needs to have known bounds + ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; const ImGuiID id = window->GetID(label); @@ -9133,9 +9387,13 @@ bool ImGui::DragFloat(const char* label, float* v, float v_speed, float v_min, f } const bool hovered = ItemHoverable(frame_bb, id); - if (!display_format) - display_format = "%.3f"; - int decimal_precision = ParseFormatPrecision(display_format, 3); + // Default format string when passing NULL + // Patch old "%.0f" format string to use "%d", read function comments for more details. + IM_ASSERT(data_type >= 0 && data_type < ImGuiDataType_COUNT); + if (format == NULL) + format = GDataTypeInfo[data_type].PrintFmt; + else if (data_type == ImGuiDataType_S32 && strcmp(format, "%d") != 0) + format = PatchFormatStringFloatToInt(format); // Tabbing or CTRL-clicking on Drag turns it into an input box bool start_text_input = false; @@ -9153,16 +9411,21 @@ bool ImGui::DragFloat(const char* label, float* v, float v_speed, float v_min, f } } if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id)) - return InputScalarAsWidgetReplacement(frame_bb, label, ImGuiDataType_Float, v, id, decimal_precision); + return InputScalarAsWidgetReplacement(frame_bb, id, label, data_type, v, format); // Actual drag behavior ItemSize(total_bb, style.FramePadding.y); - const bool value_changed = DragBehavior(frame_bb, id, v, v_speed, v_min, v_max, decimal_precision, power); + const bool value_changed = DragBehavior(id, data_type, v, v_speed, v_min, v_max, format, power); + + // Draw frame + const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg); + RenderNavHighlight(frame_bb, id); + RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, style.FrameRounding); // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. char value_buf[64]; - const char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); - RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f,0.5f)); + const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_ARRAYSIZE(value_buf), data_type, v, format); + RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f)); if (label_size.x > 0.0f) RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label); @@ -9170,7 +9433,7 @@ bool ImGui::DragFloat(const char* label, float* v, float v_speed, float v_min, f return value_changed; } -bool ImGui::DragFloatN(const char* label, float* v, int components, float v_speed, float v_min, float v_max, const char* display_format, float power) +bool ImGui::DragScalarN(const char* label, ImGuiDataType data_type, void* v, int components, float v_speed, const void* v_min, const void* v_max, const char* format, float power) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) @@ -9181,38 +9444,44 @@ bool ImGui::DragFloatN(const char* label, float* v, int components, float v_spee BeginGroup(); PushID(label); PushMultiItemsWidths(components); + size_t type_size = GDataTypeInfo[data_type].Size; for (int i = 0; i < components; i++) { PushID(i); - value_changed |= DragFloat("##v", &v[i], v_speed, v_min, v_max, display_format, power); + value_changed |= DragScalar("##v", data_type, v, v_speed, v_min, v_max, format, power); SameLine(0, g.Style.ItemInnerSpacing.x); PopID(); PopItemWidth(); + v = (void*)((char*)v + type_size); } PopID(); TextUnformatted(label, FindRenderedTextEnd(label)); EndGroup(); - return value_changed; } -bool ImGui::DragFloat2(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* display_format, float power) +bool ImGui::DragFloat(const char* label, float* v, float v_speed, float v_min, float v_max, const char* format, float power) { - return DragFloatN(label, v, 2, v_speed, v_min, v_max, display_format, power); + return DragScalar(label, ImGuiDataType_Float, v, v_speed, &v_min, &v_max, format, power); } -bool ImGui::DragFloat3(const char* label, float v[3], float v_speed, float v_min, float v_max, const char* display_format, float power) +bool ImGui::DragFloat2(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* format, float power) { - return DragFloatN(label, v, 3, v_speed, v_min, v_max, display_format, power); + return DragScalarN(label, ImGuiDataType_Float, v, 2, v_speed, &v_min, &v_max, format, power); } -bool ImGui::DragFloat4(const char* label, float v[4], float v_speed, float v_min, float v_max, const char* display_format, float power) +bool ImGui::DragFloat3(const char* label, float v[3], float v_speed, float v_min, float v_max, const char* format, float power) { - return DragFloatN(label, v, 4, v_speed, v_min, v_max, display_format, power); + return DragScalarN(label, ImGuiDataType_Float, v, 3, v_speed, &v_min, &v_max, format, power); } -bool ImGui::DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed, float v_min, float v_max, const char* display_format, const char* display_format_max, float power) +bool ImGui::DragFloat4(const char* label, float v[4], float v_speed, float v_min, float v_max, const char* format, float power) +{ + return DragScalarN(label, ImGuiDataType_Float, v, 4, v_speed, &v_min, &v_max, format, power); +} + +bool ImGui::DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed, float v_min, float v_max, const char* format, const char* format_max, float power) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) @@ -9223,10 +9492,10 @@ bool ImGui::DragFloatRange2(const char* label, float* v_current_min, float* v_cu BeginGroup(); PushMultiItemsWidths(2); - bool value_changed = DragFloat("##min", v_current_min, v_speed, (v_min >= v_max) ? -FLT_MAX : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), display_format, power); + bool value_changed = DragFloat("##min", v_current_min, v_speed, (v_min >= v_max) ? -FLT_MAX : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), format, power); PopItemWidth(); SameLine(0, g.Style.ItemInnerSpacing.x); - value_changed |= DragFloat("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? FLT_MAX : v_max, display_format_max ? display_format_max : display_format, power); + value_changed |= DragFloat("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? FLT_MAX : v_max, format_max ? format_max : format, power); PopItemWidth(); SameLine(0, g.Style.ItemInnerSpacing.x); @@ -9238,59 +9507,27 @@ bool ImGui::DragFloatRange2(const char* label, float* v_current_min, float* v_cu } // NB: v_speed is float to allow adjusting the drag speed with more precision -bool ImGui::DragInt(const char* label, int* v, float v_speed, int v_min, int v_max, const char* display_format) +bool ImGui::DragInt(const char* label, int* v, float v_speed, int v_min, int v_max, const char* format) { - if (!display_format) - display_format = "%.0f"; - float v_f = (float)*v; - bool value_changed = DragFloat(label, &v_f, v_speed, (float)v_min, (float)v_max, display_format); - *v = (int)v_f; - return value_changed; + return DragScalar(label, ImGuiDataType_S32, v, v_speed, &v_min, &v_max, format); } -bool ImGui::DragIntN(const char* label, int* v, int components, float v_speed, int v_min, int v_max, const char* display_format) +bool ImGui::DragInt2(const char* label, int v[2], float v_speed, int v_min, int v_max, const char* format) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - - ImGuiContext& g = *GImGui; - bool value_changed = false; - BeginGroup(); - PushID(label); - PushMultiItemsWidths(components); - for (int i = 0; i < components; i++) - { - PushID(i); - value_changed |= DragInt("##v", &v[i], v_speed, v_min, v_max, display_format); - SameLine(0, g.Style.ItemInnerSpacing.x); - PopID(); - PopItemWidth(); - } - PopID(); - - TextUnformatted(label, FindRenderedTextEnd(label)); - EndGroup(); - - return value_changed; + return DragScalarN(label, ImGuiDataType_S32, v, 2, v_speed, &v_min, &v_max, format); } -bool ImGui::DragInt2(const char* label, int v[2], float v_speed, int v_min, int v_max, const char* display_format) +bool ImGui::DragInt3(const char* label, int v[3], float v_speed, int v_min, int v_max, const char* format) { - return DragIntN(label, v, 2, v_speed, v_min, v_max, display_format); + return DragScalarN(label, ImGuiDataType_S32, v, 3, v_speed, &v_min, &v_max, format); } -bool ImGui::DragInt3(const char* label, int v[3], float v_speed, int v_min, int v_max, const char* display_format) +bool ImGui::DragInt4(const char* label, int v[4], float v_speed, int v_min, int v_max, const char* format) { - return DragIntN(label, v, 3, v_speed, v_min, v_max, display_format); + return DragScalarN(label, ImGuiDataType_S32, v, 4, v_speed, &v_min, &v_max, format); } -bool ImGui::DragInt4(const char* label, int v[4], float v_speed, int v_min, int v_max, const char* display_format) -{ - return DragIntN(label, v, 4, v_speed, v_min, v_max, display_format); -} - -bool ImGui::DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed, int v_min, int v_max, const char* display_format, const char* display_format_max) +bool ImGui::DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed, int v_min, int v_max, const char* format, const char* format_max) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) @@ -9301,10 +9538,10 @@ bool ImGui::DragIntRange2(const char* label, int* v_current_min, int* v_current_ BeginGroup(); PushMultiItemsWidths(2); - bool value_changed = DragInt("##min", v_current_min, v_speed, (v_min >= v_max) ? INT_MIN : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), display_format); + bool value_changed = DragInt("##min", v_current_min, v_speed, (v_min >= v_max) ? INT_MIN : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), format); PopItemWidth(); SameLine(0, g.Style.ItemInnerSpacing.x); - value_changed |= DragInt("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? INT_MAX : v_max, display_format_max ? display_format_max : display_format); + value_changed |= DragInt("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? INT_MAX : v_max, format_max ? format_max : format); PopItemWidth(); SameLine(0, g.Style.ItemInnerSpacing.x); @@ -9710,7 +9947,7 @@ static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, STB_TEXTEDIT_STRING* ob r->num_chars = (int)(text_remaining - (text + line_start_idx)); } -static bool is_separator(unsigned int c) { return ImCharIsSpace(c) || c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|'; } +static bool is_separator(unsigned int c) { return ImCharIsBlankW(c) || c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|'; } static int is_word_boundary_from_right(STB_TEXTEDIT_STRING* obj, int idx) { return idx > 0 ? (is_separator( obj->Text[idx-1] ) && !is_separator( obj->Text[idx] ) ) : 1; } static int STB_TEXTEDIT_MOVEWORDLEFT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) { idx--; while (idx >= 0 && !is_word_boundary_from_right(obj, idx)) idx--; return idx < 0 ? 0 : idx; } #ifdef __APPLE__ // FIXME: Move setting to IO structure @@ -9864,7 +10101,7 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f *p_char = (c += (unsigned int)('A'-'a')); if (flags & ImGuiInputTextFlags_CharsNoBlank) - if (ImCharIsSpace(c)) + if (ImCharIsBlankW(c)) return false; } @@ -10045,15 +10282,15 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 const float mouse_x = (io.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + edit_state.ScrollX; const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y - style.FramePadding.y) : (g.FontSize*0.5f)); - const bool osx_double_click_selects_words = io.OptMacOSXBehaviors; // OS X style: Double click selects by word instead of selecting whole text - if (select_all || (hovered && !osx_double_click_selects_words && io.MouseDoubleClicked[0])) + const bool is_osx = io.OptMacOSXBehaviors; + if (select_all || (hovered && !is_osx && io.MouseDoubleClicked[0])) { edit_state.SelectAll(); edit_state.SelectedAllMouseLock = true; } - else if (hovered && osx_double_click_selects_words && io.MouseDoubleClicked[0]) + else if (hovered && is_osx && io.MouseDoubleClicked[0]) { - // Select a word only, OS X style (by simulating keystrokes) + // Double-click select a word only, OS X style (by simulating keystrokes) edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT); edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT); } @@ -10078,7 +10315,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 { // Process text input (before we check for Return because using some IME will effectively send a Return?) // We ignore CTRL inputs, but need to allow ALT+CTRL as some keyboards (e.g. German) use AltGR (which _is_ Alt+Ctrl) to input certain characters. - if (!(io.KeyCtrl && !io.KeyAlt) && is_editable && !user_nav_input_start) + bool ignore_inputs = (io.KeyCtrl && !io.KeyAlt) || (is_osx && io.KeySuper); + if (!ignore_inputs && is_editable && !user_nav_input_start) for (int n = 0; n < IM_ARRAYSIZE(io.InputCharacters) && io.InputCharacters[n]; n++) { // Insert character if they pass filtering @@ -10097,15 +10335,19 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 { // Handle key-presses const int k_mask = (io.KeyShift ? STB_TEXTEDIT_K_SHIFT : 0); - const bool is_shortcut_key_only = (io.OptMacOSXBehaviors ? (io.KeySuper && !io.KeyCtrl) : (io.KeyCtrl && !io.KeySuper)) && !io.KeyAlt && !io.KeyShift; // OS X style: Shortcuts using Cmd/Super instead of Ctrl - const bool is_wordmove_key_down = io.OptMacOSXBehaviors ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl - const bool is_startend_key_down = io.OptMacOSXBehaviors && io.KeySuper && !io.KeyCtrl && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End + const bool is_osx = io.OptMacOSXBehaviors; + const bool is_shortcut_key = (is_osx ? (io.KeySuper && !io.KeyCtrl) : (io.KeyCtrl && !io.KeySuper)) && !io.KeyAlt && !io.KeyShift; // OS X style: Shortcuts using Cmd/Super instead of Ctrl + const bool is_osx_shift_shortcut = is_osx && io.KeySuper && io.KeyShift && !io.KeyCtrl && !io.KeyAlt; + const bool is_wordmove_key_down = is_osx ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl + const bool is_startend_key_down = is_osx && io.KeySuper && !io.KeyCtrl && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End const bool is_ctrl_key_only = io.KeyCtrl && !io.KeyShift && !io.KeyAlt && !io.KeySuper; const bool is_shift_key_only = io.KeyShift && !io.KeyCtrl && !io.KeyAlt && !io.KeySuper; - const bool is_cut = ((is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_X)) || (is_shift_key_only && IsKeyPressedMap(ImGuiKey_Delete))) && is_editable && !is_password && (!is_multiline || edit_state.HasSelection()); - const bool is_copy = ((is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_C)) || (is_ctrl_key_only && IsKeyPressedMap(ImGuiKey_Insert))) && !is_password && (!is_multiline || edit_state.HasSelection()); - const bool is_paste = ((is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_V)) || (is_shift_key_only && IsKeyPressedMap(ImGuiKey_Insert))) && is_editable; + const bool is_cut = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_X)) || (is_shift_key_only && IsKeyPressedMap(ImGuiKey_Delete))) && is_editable && !is_password && (!is_multiline || edit_state.HasSelection()); + const bool is_copy = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_C)) || (is_ctrl_key_only && IsKeyPressedMap(ImGuiKey_Insert))) && !is_password && (!is_multiline || edit_state.HasSelection()); + const bool is_paste = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_V)) || (is_shift_key_only && IsKeyPressedMap(ImGuiKey_Insert))) && is_editable; + const bool is_undo = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_Z)) && is_editable && is_undoable); + const bool is_redo = ((is_shortcut_key && IsKeyPressedMap(ImGuiKey_Y)) || (is_osx_shift_shortcut && IsKeyPressedMap(ImGuiKey_Z))) && is_editable && is_undoable; if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); } else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); } @@ -10119,7 +10361,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 if (!edit_state.HasSelection()) { if (is_wordmove_key_down) edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT|STB_TEXTEDIT_K_SHIFT); - else if (io.OptMacOSXBehaviors && io.KeySuper && !io.KeyAlt && !io.KeyCtrl) edit_state.OnKeyPressed(STB_TEXTEDIT_K_LINESTART|STB_TEXTEDIT_K_SHIFT); + else if (is_osx && io.KeySuper && !io.KeyAlt && !io.KeyCtrl) edit_state.OnKeyPressed(STB_TEXTEDIT_K_LINESTART|STB_TEXTEDIT_K_SHIFT); } edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); } @@ -10143,10 +10385,20 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 if (InputTextFilterCharacter(&c, flags, callback, user_data)) edit_state.OnKeyPressed((int)c); } - else if (IsKeyPressedMap(ImGuiKey_Escape)) { clear_active_id = cancel_edit = true; } - else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Z) && is_editable && is_undoable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); edit_state.ClearSelection(); } - else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Y) && is_editable && is_undoable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); edit_state.ClearSelection(); } - else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); edit_state.CursorFollow = true; } + else if (IsKeyPressedMap(ImGuiKey_Escape)) + { + clear_active_id = cancel_edit = true; + } + else if (is_undo || is_redo) + { + edit_state.OnKeyPressed(is_undo ? STB_TEXTEDIT_K_UNDO : STB_TEXTEDIT_K_REDO); + edit_state.ClearSelection(); + } + else if (is_shortcut_key && IsKeyPressedMap(ImGuiKey_A)) + { + edit_state.SelectAll(); + edit_state.CursorFollow = true; + } else if (is_cut || is_copy) { // Cut, Copy @@ -10158,7 +10410,6 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 ImTextStrToUtf8(edit_state.TempTextBuffer.Data, edit_state.TempTextBuffer.Size, edit_state.Text.Data+ib, edit_state.Text.Data+ie); SetClipboardText(edit_state.TempTextBuffer.Data); } - if (is_cut) { if (!edit_state.HasSelection()) @@ -10169,7 +10420,6 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 } else if (is_paste) { - // Paste if (const char* clipboard = GetClipboardText()) { // Filter pasted buffer @@ -10201,8 +10451,8 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 { if (cancel_edit) { - // Restore initial value - if (is_editable) + // Restore initial value. Only return true if restoring to the initial value changes the current buffer contents. + if (is_editable && strncmp(buf, edit_state.InitialText.Data, buf_size) != 0) { ImStrncpy(buf, edit_state.InitialText.Data, buf_size); value_changed = true; @@ -10442,7 +10692,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 draw_window->DrawList->AddText(g.Font, g.FontSize, render_pos - render_scroll, GetColorU32(ImGuiCol_Text), buf_display, buf_display + edit_state.CurLenA, 0.0f, is_multiline ? NULL : &clip_rect); // Draw blinking cursor - bool cursor_is_visible = (!g.IO.OptCursorBlink) || (g.InputTextState.CursorAnim <= 0.0f) || fmodf(g.InputTextState.CursorAnim, 1.20f) <= 0.80f; + bool cursor_is_visible = (!g.IO.OptCursorBlink) || (g.InputTextState.CursorAnim <= 0.0f) || ImFmod(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+1.0f, cursor_screen_pos.y-1.5f); if (cursor_is_visible && cursor_screen_rect.Overlaps(clip_rect)) @@ -10450,7 +10700,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // 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) - g.OsImePosRequest = ImVec2(cursor_screen_pos.x - 1, cursor_screen_pos.y - g.FontSize); + g.PlatformImePos = ImVec2(cursor_screen_pos.x - 1, cursor_screen_pos.y - g.FontSize); } else { @@ -10495,8 +10745,8 @@ bool ImGui::InputTextMultiline(const char* label, char* buf, size_t buf_size, co return InputTextEx(label, buf, (int)buf_size, size, flags | ImGuiInputTextFlags_Multiline, callback, user_data); } -// NB: scalar_format here must be a simple "%xx" format string with no prefix/suffix (unlike the Drag/Slider functions "display_format" argument) -bool ImGui::InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags) +// NB: format here must be a simple "%xx" format string with no prefix/suffix (unlike the Drag/Slider functions "format" argument) +bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* data_ptr, const void* step, const void* step_fast, const char* format, ImGuiInputTextFlags extra_flags) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) @@ -10504,84 +10754,78 @@ bool ImGui::InputScalarEx(const char* label, ImGuiDataType data_type, void* data ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; - const ImVec2 label_size = CalcTextSize(label, NULL, true); - BeginGroup(); - PushID(label); - const ImVec2 button_sz = ImVec2(GetFrameHeight(), GetFrameHeight()); - if (step_ptr) - PushItemWidth(ImMax(1.0f, CalcItemWidth() - (button_sz.x + style.ItemInnerSpacing.x)*2)); + IM_ASSERT(data_type >= 0 && data_type < ImGuiDataType_COUNT); + if (format == NULL) + format = GDataTypeInfo[data_type].PrintFmt; char buf[64]; - DataTypeFormatString(data_type, data_ptr, scalar_format, buf, IM_ARRAYSIZE(buf)); + DataTypeFormatString(buf, IM_ARRAYSIZE(buf), data_type, data_ptr, format); bool value_changed = false; if ((extra_flags & (ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsScientific)) == 0) extra_flags |= ImGuiInputTextFlags_CharsDecimal; extra_flags |= ImGuiInputTextFlags_AutoSelectAll; - if (InputText("", buf, IM_ARRAYSIZE(buf), extra_flags)) // PushId(label) + "" gives us the expected ID from outside point of view - value_changed = DataTypeApplyOpFromText(buf, GImGui->InputTextState.InitialText.begin(), data_type, data_ptr, scalar_format); - // Step buttons - if (step_ptr) + if (step != NULL) { + const float button_size = GetFrameHeight(); + + BeginGroup(); // The only purpose of the group here is to allow the caller to query item data e.g. IsItemActive() + PushID(label); + PushItemWidth(ImMax(1.0f, CalcItemWidth() - (button_size + style.ItemInnerSpacing.x) * 2)); + if (InputText("", buf, IM_ARRAYSIZE(buf), extra_flags)) // PushId(label) + "" gives us the expected ID from outside point of view + value_changed = DataTypeApplyOpFromText(buf, g.InputTextState.InitialText.Data, data_type, data_ptr, format); PopItemWidth(); + + // Step buttons SameLine(0, style.ItemInnerSpacing.x); - if (ButtonEx("-", button_sz, ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups)) + if (ButtonEx("-", ImVec2(button_size, button_size), ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups)) { - DataTypeApplyOp(data_type, '-', data_ptr, data_ptr, g.IO.KeyCtrl && step_fast_ptr ? step_fast_ptr : step_ptr); + DataTypeApplyOp(data_type, '-', data_ptr, data_ptr, g.IO.KeyCtrl && step_fast ? step_fast : step); value_changed = true; } SameLine(0, style.ItemInnerSpacing.x); - if (ButtonEx("+", button_sz, ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups)) + if (ButtonEx("+", ImVec2(button_size, button_size), ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups)) { - DataTypeApplyOp(data_type, '+', data_ptr, data_ptr, g.IO.KeyCtrl && step_fast_ptr ? step_fast_ptr : step_ptr); + DataTypeApplyOp(data_type, '+', data_ptr, data_ptr, g.IO.KeyCtrl && step_fast ? step_fast : step); value_changed = true; } - } - PopID(); + SameLine(0, style.ItemInnerSpacing.x); + TextUnformatted(label, FindRenderedTextEnd(label)); - if (label_size.x > 0) + PopID(); + EndGroup(); + } + else { - SameLine(0, style.ItemInnerSpacing.x); - RenderText(ImVec2(window->DC.CursorPos.x, window->DC.CursorPos.y + style.FramePadding.y), label); - ItemSize(label_size, style.FramePadding.y); + if (InputText(label, buf, IM_ARRAYSIZE(buf), extra_flags)) + value_changed = DataTypeApplyOpFromText(buf, g.InputTextState.InitialText.Data, data_type, data_ptr, format); } - EndGroup(); return value_changed; } -bool ImGui::InputFloat(const char* label, float* v, float step, float step_fast, int decimal_precision, ImGuiInputTextFlags extra_flags) +bool ImGui::InputFloat(const char* label, float* v, float step, float step_fast, const char* format, ImGuiInputTextFlags extra_flags) { extra_flags |= ImGuiInputTextFlags_CharsScientific; - if (decimal_precision < 0) - { - // Ideally we'd have a minimum decimal precision of 1 to visually denote that this is a float, while hiding non-significant digits? %f doesn't have a minimum of 1 - return InputScalarEx(label, ImGuiDataType_Float, (void*)v, (void*)(step>0.0f ? &step : NULL), (void*)(step_fast>0.0f ? &step_fast : NULL), "%f", extra_flags); - } - else - { - char display_format[16]; - ImFormatString(display_format, IM_ARRAYSIZE(display_format), "%%.%df", decimal_precision); - return InputScalarEx(label, ImGuiDataType_Float, (void*)v, (void*)(step>0.0f ? &step : NULL), (void*)(step_fast>0.0f ? &step_fast : NULL), display_format, extra_flags); - } + return InputScalar(label, ImGuiDataType_Float, (void*)v, (void*)(step>0.0f ? &step : NULL), (void*)(step_fast>0.0f ? &step_fast : NULL), format, extra_flags); } -bool ImGui::InputDouble(const char* label, double* v, double step, double step_fast, const char* display_format, ImGuiInputTextFlags extra_flags) +bool ImGui::InputDouble(const char* label, double* v, double step, double step_fast, const char* format, ImGuiInputTextFlags extra_flags) { extra_flags |= ImGuiInputTextFlags_CharsScientific; - return InputScalarEx(label, ImGuiDataType_Double, (void*)v, (void*)(step>0.0 ? &step : NULL), (void*)(step_fast>0.0 ? &step_fast : NULL), display_format, extra_flags); + return InputScalar(label, ImGuiDataType_Double, (void*)v, (void*)(step>0.0 ? &step : NULL), (void*)(step_fast>0.0 ? &step_fast : NULL), format, extra_flags); } bool ImGui::InputInt(const char* label, int* v, int step, int step_fast, ImGuiInputTextFlags extra_flags) { // Hexadecimal input provided as a convenience but the flag name is awkward. Typically you'd use InputText() to parse your own data, if you want to handle prefixes. - const char* scalar_format = (extra_flags & ImGuiInputTextFlags_CharsHexadecimal) ? "%08X" : "%d"; - return InputScalarEx(label, ImGuiDataType_Int, (void*)v, (void*)(step>0 ? &step : NULL), (void*)(step_fast>0 ? &step_fast : NULL), scalar_format, extra_flags); + const char* format = (extra_flags & ImGuiInputTextFlags_CharsHexadecimal) ? "%08X" : "%d"; + return InputScalar(label, ImGuiDataType_S32, (void*)v, (void*)(step>0 ? &step : NULL), (void*)(step_fast>0 ? &step_fast : NULL), format, extra_flags); } -bool ImGui::InputFloatN(const char* label, float* v, int components, int decimal_precision, ImGuiInputTextFlags extra_flags) +bool ImGui::InputScalarN(const char* label, ImGuiDataType data_type, void* v, int components, const void* step, const void* step_fast, const char* format, ImGuiInputTextFlags extra_flags) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) @@ -10592,13 +10836,15 @@ bool ImGui::InputFloatN(const char* label, float* v, int components, int decimal BeginGroup(); PushID(label); PushMultiItemsWidths(components); + size_t type_size = GDataTypeInfo[data_type].Size; for (int i = 0; i < components; i++) { PushID(i); - value_changed |= InputFloat("##v", &v[i], 0, 0, decimal_precision, extra_flags); + value_changed |= InputScalar("##v", data_type, v, step, step_fast, format, extra_flags); SameLine(0, g.Style.ItemInnerSpacing.x); PopID(); PopItemWidth(); + v = (void*)((char*)v + type_size); } PopID(); @@ -10608,61 +10854,69 @@ bool ImGui::InputFloatN(const char* label, float* v, int components, int decimal return value_changed; } -bool ImGui::InputFloat2(const char* label, float v[2], int decimal_precision, ImGuiInputTextFlags extra_flags) +bool ImGui::InputFloat2(const char* label, float v[2], const char* format, ImGuiInputTextFlags extra_flags) { - return InputFloatN(label, v, 2, decimal_precision, extra_flags); + return InputScalarN(label, ImGuiDataType_Float, v, 2, NULL, NULL, format, extra_flags); } -bool ImGui::InputFloat3(const char* label, float v[3], int decimal_precision, ImGuiInputTextFlags extra_flags) +bool ImGui::InputFloat3(const char* label, float v[3], const char* format, ImGuiInputTextFlags extra_flags) { - return InputFloatN(label, v, 3, decimal_precision, extra_flags); + return InputScalarN(label, ImGuiDataType_Float, v, 3, NULL, NULL, format, extra_flags); } -bool ImGui::InputFloat4(const char* label, float v[4], int decimal_precision, ImGuiInputTextFlags extra_flags) +bool ImGui::InputFloat4(const char* label, float v[4], const char* format, ImGuiInputTextFlags extra_flags) { - return InputFloatN(label, v, 4, decimal_precision, extra_flags); + return InputScalarN(label, ImGuiDataType_Float, v, 4, NULL, NULL, format, extra_flags); } -bool ImGui::InputIntN(const char* label, int* v, int components, ImGuiInputTextFlags extra_flags) +// Prefer using "const char* format" directly, which is more flexible and consistent with other API. +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS +bool ImGui::InputFloat(const char* label, float* v, float step, float step_fast, int decimal_precision, ImGuiInputTextFlags extra_flags) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + char format[16] = "%f"; + if (decimal_precision >= 0) + ImFormatString(format, IM_ARRAYSIZE(format), "%%.%df", decimal_precision); + return InputFloat(label, v, step, step_fast, format, extra_flags); +} - ImGuiContext& g = *GImGui; - bool value_changed = false; - BeginGroup(); - PushID(label); - PushMultiItemsWidths(components); - for (int i = 0; i < components; i++) - { - PushID(i); - value_changed |= InputInt("##v", &v[i], 0, 0, extra_flags); - SameLine(0, g.Style.ItemInnerSpacing.x); - PopID(); - PopItemWidth(); - } - PopID(); +bool ImGui::InputFloat2(const char* label, float v[2], int decimal_precision, ImGuiInputTextFlags extra_flags) +{ + char format[16] = "%f"; + if (decimal_precision >= 0) + ImFormatString(format, IM_ARRAYSIZE(format), "%%.%df", decimal_precision); + return InputScalarN(label, ImGuiDataType_Float, v, 2, NULL, NULL, format, extra_flags); +} - TextUnformatted(label, FindRenderedTextEnd(label)); - EndGroup(); +bool ImGui::InputFloat3(const char* label, float v[3], int decimal_precision, ImGuiInputTextFlags extra_flags) +{ + char format[16] = "%f"; + if (decimal_precision >= 0) + ImFormatString(format, IM_ARRAYSIZE(format), "%%.%df", decimal_precision); + return InputScalarN(label, ImGuiDataType_Float, v, 3, NULL, NULL, format, extra_flags); +} - return value_changed; +bool ImGui::InputFloat4(const char* label, float v[4], int decimal_precision, ImGuiInputTextFlags extra_flags) +{ + char format[16] = "%f"; + if (decimal_precision >= 0) + ImFormatString(format, IM_ARRAYSIZE(format), "%%.%df", decimal_precision); + return InputScalarN(label, ImGuiDataType_Float, v, 4, NULL, NULL, format, extra_flags); } +#endif // IMGUI_DISABLE_OBSOLETE_FUNCTIONS bool ImGui::InputInt2(const char* label, int v[2], ImGuiInputTextFlags extra_flags) { - return InputIntN(label, v, 2, extra_flags); + return InputScalarN(label, ImGuiDataType_S32, v, 2, NULL, NULL, "%d", extra_flags); } bool ImGui::InputInt3(const char* label, int v[3], ImGuiInputTextFlags extra_flags) { - return InputIntN(label, v, 3, extra_flags); + return InputScalarN(label, ImGuiDataType_S32, v, 3, NULL, NULL, "%d", extra_flags); } bool ImGui::InputInt4(const char* label, int v[4], ImGuiInputTextFlags extra_flags) { - return InputIntN(label, v, 4, extra_flags); + return InputScalarN(label, ImGuiDataType_S32, v, 4, NULL, NULL, "%d", extra_flags); } static float CalcMaxPopupHeightFromItemCount(int items_count) @@ -10757,31 +11011,29 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF ImVec2 size_expected = CalcSizeAfterConstraint(popup_window, CalcSizeAutoFit(popup_window, size_contents)); if (flags & ImGuiComboFlags_PopupAlignLeft) popup_window->AutoPosLastDirection = ImGuiDir_Left; - ImVec2 pos = FindBestWindowPosForPopup(frame_bb.GetBL(), size_expected, &popup_window->AutoPosLastDirection, frame_bb, ImGuiPopupPositionPolicy_ComboBox); + ImRect r_outer = FindAllowedExtentRectForWindow(popup_window); + ImVec2 pos = FindBestWindowPosForPopupEx(frame_bb.GetBL(), size_expected, &popup_window->AutoPosLastDirection, r_outer, frame_bb, ImGuiPopupPositionPolicy_ComboBox); SetNextWindowPos(pos); } + // Horizontally align ourselves with the framed text + PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(style.FramePadding.x, style.WindowPadding.y)); + ImGuiWindowFlags window_flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_Popup | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings; if (!Begin(name, NULL, window_flags)) { EndPopup(); + PopStyleVar(); IM_ASSERT(0); // This should never happen as we tested for IsPopupOpen() above return false; } - - // Horizontally align ourselves with the framed text - if (style.FramePadding.x != style.WindowPadding.x) - Indent(style.FramePadding.x - style.WindowPadding.x); - return true; } void ImGui::EndCombo() { - const ImGuiStyle& style = GImGui->Style; - if (style.FramePadding.x != style.WindowPadding.x) - Unindent(style.FramePadding.x - style.WindowPadding.x); EndPopup(); + PopStyleVar(); } // Old API, prefer using BeginCombo() nowadays if you can. @@ -10793,7 +11045,7 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi if (*current_item >= 0 && *current_item < items_count) items_getter(data, *current_item, &preview_text); - // The old Combo() API exposed "popup_max_height_in_items", however the new more general BeginCombo() API doesn't, so we emulate it here. + // The old Combo() API exposed "popup_max_height_in_items". The new more general BeginCombo() API doesn't, so we emulate it here. if (popup_max_height_in_items != -1 && !g.NextWindowData.SizeConstraintCond) { float popup_max_height = CalcMaxPopupHeightFromItemCount(popup_max_height_in_items); @@ -10934,8 +11186,8 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl selected = false; // Hovering selectable with mouse updates NavId accordingly so navigation can be resumed with gamepad/keyboard (this doesn't happen on most widgets) - if (pressed || hovered)// && (g.IO.MouseDelta.x != 0.0f || g.IO.MouseDelta.y != 0.0f)) - if (!g.NavDisableMouseHover && g.NavWindow == window && g.NavLayer == window->DC.NavLayerActiveMask) + if (pressed || hovered) + if (!g.NavDisableMouseHover && g.NavWindow == window && g.NavLayer == window->DC.NavLayerCurrent) { g.NavDisableHighlight = true; SetNavID(id, window->DC.NavLayerCurrent); @@ -11005,7 +11257,7 @@ bool ImGui::ListBoxHeader(const char* label, const ImVec2& size_arg) bool ImGui::ListBoxHeader(const char* label, int items_count, int height_in_items) { // Size default to hold ~7 items. Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar. - // However we don't add +0.40f if items_count <= height_in_items. It is slightly dodgy, because it means a dynamic list of items will make the widget resize occasionally when it crosses that size. + // We don't add +0.40f if items_count <= height_in_items. It is slightly dodgy, because it means a dynamic list of items will make the widget resize occasionally when it crosses that size. // I am expecting that someone will come and complain about this behavior in a remote future, then we can advise on a better solution. if (height_in_items < 0) height_in_items = ImMin(items_count, 7); @@ -11123,21 +11375,24 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool* p_selected, return false; } +// For the main menu bar, which cannot be moved, we honor g.Style.DisplaySafeAreaPadding to ensure text can be visible on a TV set. bool ImGui::BeginMainMenuBar() { ImGuiContext& g = *GImGui; + g.NextWindowData.MenuBarOffsetMinVal = ImVec2(g.Style.DisplaySafeAreaPadding.x, ImMax(g.Style.DisplaySafeAreaPadding.y - g.Style.FramePadding.y, 0.0f)); SetNextWindowPos(ImVec2(0.0f, 0.0f)); - SetNextWindowSize(ImVec2(g.IO.DisplaySize.x, g.FontBaseSize + g.Style.FramePadding.y * 2.0f)); + SetNextWindowSize(ImVec2(g.IO.DisplaySize.x, g.NextWindowData.MenuBarOffsetMinVal.y + g.FontBaseSize + g.Style.FramePadding.y)); PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0,0)); - if (!Begin("##MainMenuBar", NULL, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_MenuBar) - || !BeginMenuBar()) + ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_MenuBar; + bool is_open = Begin("##MainMenuBar", NULL, window_flags) && BeginMenuBar(); + g.NextWindowData.MenuBarOffsetMinVal = ImVec2(0.0f, 0.0f); + if (!is_open) { End(); PopStyleVar(2); return false; } - g.CurrentWindow->DC.MenuBarOffsetX += g.Style.DisplaySafeAreaPadding.x; return true; } @@ -11166,14 +11421,14 @@ bool ImGui::BeginMenuBar() BeginGroup(); // Save position PushID("##menubar"); - // We don't clip with regular window clipping rectangle as it is already set to the area below. However we clip with window full rect. - // We remove 1 worth of rounding to Max.x to that text in long menus don't tend to display over the lower-right rounded area, which looks particularly glitchy. + // We don't clip with current window clipping rectangle as it is already set to the area below. However we clip with window full rect. + // We remove 1 worth of rounding to Max.x to that text in long menus and small windows don't tend to display over the lower-right rounded area, which looks particularly glitchy. ImRect bar_rect = window->MenuBarRect(); ImRect clip_rect(ImFloor(bar_rect.Min.x + 0.5f), ImFloor(bar_rect.Min.y + window->WindowBorderSize + 0.5f), ImFloor(ImMax(bar_rect.Min.x, bar_rect.Max.x - window->WindowRounding) + 0.5f), ImFloor(bar_rect.Max.y + 0.5f)); - clip_rect.ClipWith(window->WindowRectClipped); + clip_rect.ClipWith(window->OuterRectClipped); PushClipRect(clip_rect.Min, clip_rect.Max, false); - window->DC.CursorPos = ImVec2(bar_rect.Min.x + window->DC.MenuBarOffsetX, bar_rect.Min.y);// + g.Style.FramePadding.y); + window->DC.CursorPos = ImVec2(bar_rect.Min.x + window->DC.MenuBarOffset.x, bar_rect.Min.y + window->DC.MenuBarOffset.y); window->DC.LayoutType = ImGuiLayoutType_Horizontal; window->DC.NavLayerCurrent++; window->DC.NavLayerCurrentMask <<= 1; @@ -11213,7 +11468,7 @@ void ImGui::EndMenuBar() IM_ASSERT(window->DC.MenuBarAppending); PopClipRect(); PopID(); - window->DC.MenuBarOffsetX = window->DC.CursorPos.x - window->MenuBarRect().Min.x; + window->DC.MenuBarOffset.x = window->DC.CursorPos.x - window->MenuBarRect().Min.x; // Save horizontal position so next append can reuse it. This is kinda equivalent to a per-layer CursorPos. window->DC.GroupStack.back().AdvanceCursor = false; EndGroup(); window->DC.LayoutType = ImGuiLayoutType_Vertical; @@ -11241,13 +11496,13 @@ bool ImGui::BeginMenu(const char* label, bool enabled) if (menuset_is_open) g.NavWindow = window; // Odd hack to allow hovering across menus of a same menu-set (otherwise we wouldn't be able to hover parent) - // The reference position stored in popup_pos will be used by Begin() to find a suitable position for the child menu (using FindBestPopupWindowPos). + // The reference position stored in popup_pos will be used by Begin() to find a suitable position for the child menu (using FindBestWindowPosForPopup). ImVec2 popup_pos, pos = window->DC.CursorPos; if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) { // Menu inside an horizontal menu bar // Selectable extend their highlight by half ItemSpacing in each direction. - // For ChildMenu, the popup position will be overwritten by the call to FindBestPopupWindowPos() in Begin() + // For ChildMenu, the popup position will be overwritten by the call to FindBestWindowPosForPopup() in Begin() popup_pos = ImVec2(pos.x - window->WindowPadding.x, pos.y - style.FramePadding.y + window->MenuBarHeight()); window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f); @@ -11285,7 +11540,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) ImVec2 ta = g.IO.MousePos - g.IO.MouseDelta; ImVec2 tb = (window->Pos.x < next_window->Pos.x) ? next_window_rect.GetTL() : next_window_rect.GetTR(); ImVec2 tc = (window->Pos.x < next_window->Pos.x) ? next_window_rect.GetBL() : next_window_rect.GetBR(); - float extra = ImClamp(fabsf(ta.x - tb.x) * 0.30f, 5.0f, 30.0f); // add a bit of extra slack. + float extra = ImClamp(ImFabs(ta.x - tb.x) * 0.30f, 5.0f, 30.0f); // add a bit of extra slack. ta.x += (window->Pos.x < next_window->Pos.x) ? -0.5f : +0.5f; // to avoid numerical issues tb.y = ta.y + ImMax((tb.y - extra) - ta.y, -100.0f); // triangle is maximum 200 high to limit the slope and the bias toward large sub-menus // FIXME: Multiply by fb_scale? tc.y = ta.y + ImMin((tc.y + extra) - ta.y, +100.0f); @@ -11345,8 +11600,9 @@ bool ImGui::BeginMenu(const char* label, bool enabled) if (menu_is_open) { + // Sub-menus are ChildWindow so that mouse can be hovering across them (otherwise top-most popup menu would steal focus and not allow hovering on parent menu) SetNextWindowPos(popup_pos, ImGuiCond_Always); - ImGuiWindowFlags flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); + ImGuiWindowFlags flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) } @@ -11357,7 +11613,7 @@ void ImGui::EndMenu() { // Nav: When a left move request _within our child menu_ failed, close the menu. // A menu doesn't close itself because EndMenuBar() wants the catch the last Left<>Right inputs. - // However it means that with the current code, a BeginMenu() from outside another menu or a menu-bar won't be closable with the Left direction. + // However, it means that with the current code, a BeginMenu() from outside another menu or a menu-bar won't be closable with the Left direction. ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; if (g.NavWindow && g.NavWindow->ParentWindow == window && g.NavMoveDir == ImGuiDir_Left && NavMoveRequestButNoResultYet() && window->DC.LayoutType == ImGuiLayoutType_Vertical) @@ -11544,15 +11800,15 @@ void ImGui::ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags) ImGuiColorEditFlags opts = g.ColorEditOptions; if (allow_opt_inputs) { - if (RadioButton("RGB", (opts & ImGuiColorEditFlags_RGB) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_RGB; - if (RadioButton("HSV", (opts & ImGuiColorEditFlags_HSV) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_HSV; - if (RadioButton("HEX", (opts & ImGuiColorEditFlags_HEX) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_HEX; + if (RadioButton("RGB", (opts & ImGuiColorEditFlags_RGB) != 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_RGB; + if (RadioButton("HSV", (opts & ImGuiColorEditFlags_HSV) != 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_HSV; + if (RadioButton("HEX", (opts & ImGuiColorEditFlags_HEX) != 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_HEX; } if (allow_opt_datatype) { if (allow_opt_inputs) Separator(); - if (RadioButton("0..255", (opts & ImGuiColorEditFlags_Uint8) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__DataTypeMask) | ImGuiColorEditFlags_Uint8; - if (RadioButton("0.00..1.00", (opts & ImGuiColorEditFlags_Float) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__DataTypeMask) | ImGuiColorEditFlags_Float; + if (RadioButton("0..255", (opts & ImGuiColorEditFlags_Uint8) != 0)) opts = (opts & ~ImGuiColorEditFlags__DataTypeMask) | ImGuiColorEditFlags_Uint8; + if (RadioButton("0.00..1.00", (opts & ImGuiColorEditFlags_Float) != 0)) opts = (opts & ~ImGuiColorEditFlags__DataTypeMask) | ImGuiColorEditFlags_Float; } if (allow_opt_inputs || allow_opt_datatype) @@ -11636,15 +11892,11 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag const float w_items_all = CalcItemWidth() - w_extra; const char* label_display_end = FindRenderedTextEnd(label); - const bool alpha = (flags & ImGuiColorEditFlags_NoAlpha) == 0; - const bool hdr = (flags & ImGuiColorEditFlags_HDR) != 0; - const int components = alpha ? 4 : 3; - const ImGuiColorEditFlags flags_untouched = flags; - BeginGroup(); PushID(label); // If we're not showing any slider there's no point in doing any HSV conversions + const ImGuiColorEditFlags flags_untouched = flags; if (flags & ImGuiColorEditFlags_NoInputs) flags = (flags & (~ImGuiColorEditFlags__InputsMask)) | ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_NoOptions; @@ -11661,6 +11913,10 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag flags |= (g.ColorEditOptions & ImGuiColorEditFlags__PickerMask); flags |= (g.ColorEditOptions & ~(ImGuiColorEditFlags__InputsMask | ImGuiColorEditFlags__DataTypeMask | ImGuiColorEditFlags__PickerMask)); + const bool alpha = (flags & ImGuiColorEditFlags_NoAlpha) == 0; + const bool hdr = (flags & ImGuiColorEditFlags_HDR) != 0; + const int components = alpha ? 4 : 3; + // Convert to the formats we need float f[4] = { col[0], col[1], col[2], alpha ? col[3] : 1.0f }; if (flags & ImGuiColorEditFlags_HSV) @@ -11680,9 +11936,9 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag const char* ids[4] = { "##X", "##Y", "##Z", "##W" }; const char* fmt_table_int[3][4] = { - { "%3.0f", "%3.0f", "%3.0f", "%3.0f" }, // Short display - { "R:%3.0f", "G:%3.0f", "B:%3.0f", "A:%3.0f" }, // Long display for RGBA - { "H:%3.0f", "S:%3.0f", "V:%3.0f", "A:%3.0f" } // Long display for HSVA + { "%3d", "%3d", "%3d", "%3d" }, // Short display + { "R:%3d", "G:%3d", "B:%3d", "A:%3d" }, // Long display for RGBA + { "H:%3d", "S:%3d", "V:%3d", "A:%3d" } // Long display for HSVA }; const char* fmt_table_float[3][4] = { @@ -11722,7 +11978,7 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag { value_changed = true; char* p = buf; - while (*p == '#' || ImCharIsSpace((unsigned int)*p)) + while (*p == '#' || ImCharIsBlankA(*p)) p++; i[0] = i[1] = i[2] = i[3] = 0; if (alpha) @@ -11924,13 +12180,13 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl if (initial_dist2 >= (wheel_r_inner-1)*(wheel_r_inner-1) && initial_dist2 <= (wheel_r_outer+1)*(wheel_r_outer+1)) { // Interactive with Hue wheel - H = atan2f(current_off.y, current_off.x) / IM_PI*0.5f; + H = ImAtan2(current_off.y, current_off.x) / IM_PI*0.5f; if (H < 0.0f) H += 1.0f; value_changed = value_changed_h = true; } - float cos_hue_angle = cosf(-H * 2.0f * IM_PI); - float sin_hue_angle = sinf(-H * 2.0f * IM_PI); + float cos_hue_angle = ImCos(-H * 2.0f * IM_PI); + float sin_hue_angle = ImSin(-H * 2.0f * IM_PI); if (ImTriangleContainsPoint(triangle_pa, triangle_pb, triangle_pc, ImRotate(initial_off, cos_hue_angle, sin_hue_angle))) { // Interacting with SV triangle @@ -12076,14 +12332,14 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl const int vert_end_idx = draw_list->VtxBuffer.Size; // Paint colors over existing vertices - ImVec2 gradient_p0(wheel_center.x + cosf(a0) * wheel_r_inner, wheel_center.y + sinf(a0) * wheel_r_inner); - ImVec2 gradient_p1(wheel_center.x + cosf(a1) * wheel_r_inner, wheel_center.y + sinf(a1) * wheel_r_inner); + ImVec2 gradient_p0(wheel_center.x + ImCos(a0) * wheel_r_inner, wheel_center.y + ImSin(a0) * wheel_r_inner); + ImVec2 gradient_p1(wheel_center.x + ImCos(a1) * wheel_r_inner, wheel_center.y + ImSin(a1) * wheel_r_inner); ShadeVertsLinearColorGradientKeepAlpha(draw_list->VtxBuffer.Data + vert_start_idx, draw_list->VtxBuffer.Data + vert_end_idx, gradient_p0, gradient_p1, hue_colors[n], hue_colors[n+1]); } // Render Cursor + preview on Hue Wheel - float cos_hue_angle = cosf(H * 2.0f * IM_PI); - float sin_hue_angle = sinf(H * 2.0f * IM_PI); + float cos_hue_angle = ImCos(H * 2.0f * IM_PI); + float sin_hue_angle = ImSin(H * 2.0f * IM_PI); ImVec2 hue_cursor_pos(wheel_center.x + cos_hue_angle * (wheel_r_inner+wheel_r_outer)*0.5f, wheel_center.y + sin_hue_angle * (wheel_r_inner+wheel_r_outer)*0.5f); float hue_cursor_rad = value_changed_h ? wheel_thickness * 0.65f : wheel_thickness * 0.55f; int hue_cursor_segments = ImClamp((int)(hue_cursor_rad / 1.4f), 9, 32); @@ -12646,7 +12902,7 @@ void ImGui::EndColumns() columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y); window->DC.CursorPos.y = columns->LineMaxY; if (!(columns->Flags & ImGuiColumnsFlags_GrowParentContentsSize)) - window->DC.CursorMaxPos.x = ImMax(columns->StartMaxPosX, columns->MaxX); // Restore cursor max pos, as columns don't grow parent + window->DC.CursorMaxPos.x = columns->StartMaxPosX; // Restore cursor max pos, as columns don't grow parent // Draw columns borders and handle resize bool is_being_resized = false; @@ -12950,14 +13206,14 @@ bool ImGui::SetDragDropPayload(const char* type, const void* data, size_t data_s // Store in heap g.DragDropPayloadBufHeap.resize((int)data_size); payload.Data = g.DragDropPayloadBufHeap.Data; - memcpy((void*)(intptr_t)payload.Data, data, data_size); + memcpy(payload.Data, data, data_size); } else if (data_size > 0) { // Store locally memset(&g.DragDropPayloadBufLocal, 0, sizeof(g.DragDropPayloadBufLocal)); payload.Data = g.DragDropPayloadBufLocal; - memcpy((void*)(intptr_t)payload.Data, data, data_size); + memcpy(payload.Data, data, data_size); } else { @@ -13185,19 +13441,19 @@ static void ImeSetInputScreenPosFn_DefaultImpl(int, int) {} #endif //----------------------------------------------------------------------------- -// HELP +// HELP, METRICS //----------------------------------------------------------------------------- void ImGui::ShowMetricsWindow(bool* p_open) { if (ImGui::Begin("ImGui Metrics", p_open)) { + static bool show_draw_cmd_clip_rects = true; ImGui::Text("Dear ImGui %s", ImGui::GetVersion()); ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); ImGui::Text("%d vertices, %d indices (%d triangles)", ImGui::GetIO().MetricsRenderVertices, ImGui::GetIO().MetricsRenderIndices, ImGui::GetIO().MetricsRenderIndices / 3); ImGui::Text("%d allocations", (int)GImAllocatorActiveAllocationsCount); - static bool show_clip_rects = true; - ImGui::Checkbox("Show clipping rectangles when hovering draw commands", &show_clip_rects); + ImGui::Checkbox("Show clipping rectangles when hovering draw commands", &show_draw_cmd_clip_rects); ImGui::Separator(); struct Funcs @@ -13213,8 +13469,8 @@ void ImGui::ShowMetricsWindow(bool* p_open) return; } - ImDrawList* overlay_draw_list = ImGui::GetOverlayDrawList(); // Render additional visuals into the top-most draw list - if (window && ImGui::IsItemHovered()) + ImDrawList* overlay_draw_list = GetOverlayDrawList(); // Render additional visuals into the top-most draw list + if (window && IsItemHovered()) overlay_draw_list->AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255, 255, 0, 255)); if (!node_open) return; @@ -13231,7 +13487,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) } ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL; bool pcmd_node_open = ImGui::TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "Draw %4d %s vtx, tex 0x%p, clip_rect (%4.0f,%4.0f)-(%4.0f,%4.0f)", pcmd->ElemCount, draw_list->IdxBuffer.Size > 0 ? "indexed" : "non-indexed", pcmd->TextureId, pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w); - if (show_clip_rects && ImGui::IsItemHovered()) + if (show_draw_cmd_clip_rects && ImGui::IsItemHovered()) { ImRect clip_rect = pcmd->ClipRect; ImRect vtxs_rect; @@ -13294,11 +13550,12 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGui::BulletText("Active: %d, WriteAccessed: %d", window->Active, window->WriteAccessed); ImGui::BulletText("NavLastIds: 0x%08X,0x%08X, NavLayerActiveMask: %X", window->NavLastIds[0], window->NavLastIds[1], window->DC.NavLayerActiveMask); ImGui::BulletText("NavLastChildNavWindow: %s", window->NavLastChildNavWindow ? window->NavLastChildNavWindow->Name : "NULL"); - if (window->NavRectRel[0].IsInverted()) + if (!window->NavRectRel[0].IsInverted()) ImGui::BulletText("NavRectRel[0]: (%.1f,%.1f)(%.1f,%.1f)", window->NavRectRel[0].Min.x, window->NavRectRel[0].Min.y, window->NavRectRel[0].Max.x, window->NavRectRel[0].Max.y); else ImGui::BulletText("NavRectRel[0]: "); if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow"); + if (window->ParentWindow != NULL) NodeWindow(window->ParentWindow, "ParentWindow"); if (window->DC.ChildWindows.Size > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows"); if (window->ColumnsStorage.Size > 0 && ImGui::TreeNode("Columns", "Columns sets (%d)", window->ColumnsStorage.Size)) { diff --git a/src/imgui/imgui_draw.cpp b/src/imgui/imgui_draw.cpp index 00650329..8ba9f098 100755 --- a/src/imgui/imgui_draw.cpp +++ b/src/imgui/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.60 +// dear imgui, v1.61 // (drawing and font code) // Contains implementation for @@ -91,6 +91,7 @@ namespace IMGUI_STB_NAMESPACE #pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers #endif +#ifndef STB_RECT_PACK_IMPLEMENTATION // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds) #ifndef IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION #define STBRP_STATIC #define STBRP_ASSERT(x) IM_ASSERT(x) @@ -101,11 +102,19 @@ namespace IMGUI_STB_NAMESPACE #else #include "stb_rect_pack.h" #endif +#endif +#ifndef STB_TRUETYPE_IMPLEMENTATION // in case the user already have an implementation in the _same_ compilation unit (e.g. unity builds) #ifndef IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION -#define STBTT_malloc(x,u) ((void)(u), ImGui::MemAlloc(x)) -#define STBTT_free(x,u) ((void)(u), ImGui::MemFree(x)) -#define STBTT_assert(x) IM_ASSERT(x) +#define STBTT_malloc(x,u) ((void)(u), ImGui::MemAlloc(x)) +#define STBTT_free(x,u) ((void)(u), ImGui::MemFree(x)) +#define STBTT_assert(x) IM_ASSERT(x) +#define STBTT_fmod(x,y) ImFmod(x,y) +#define STBTT_sqrt(x) ImSqrt(x) +#define STBTT_pow(x,y) ImPow(x,y) +#define STBTT_fabs(x) ImFabs(x) +#define STBTT_ifloor(x) ((int)ImFloorStd(x)) +#define STBTT_iceil(x) ((int)ImCeil(x)) #define STBTT_STATIC #define STB_TRUETYPE_IMPLEMENTATION #else @@ -116,6 +125,7 @@ namespace IMGUI_STB_NAMESPACE #else #include "stb_truetype.h" #endif +#endif #ifdef __GNUC__ #pragma GCC diagnostic pop @@ -244,8 +254,6 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst) colors[ImGuiCol_Text] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); - //colors[ImGuiCol_TextHovered] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); - //colors[ImGuiCol_TextActive] = ImVec4(1.00f, 1.00f, 0.00f, 1.00f); colors[ImGuiCol_WindowBg] = ImVec4(0.94f, 0.94f, 0.94f, 1.00f); colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); colors[ImGuiCol_PopupBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.98f); @@ -303,7 +311,7 @@ ImDrawListSharedData::ImDrawListSharedData() for (int i = 0; i < IM_ARRAYSIZE(CircleVtx12); i++) { const float a = ((float)i * 2 * IM_PI) / (float)IM_ARRAYSIZE(CircleVtx12); - CircleVtx12[i] = ImVec2(cosf(a), sinf(a)); + CircleVtx12[i] = ImVec2(ImCos(a), ImSin(a)); } } @@ -901,7 +909,7 @@ void ImDrawList::PathArcTo(const ImVec2& centre, float radius, float a_min, floa for (int i = 0; i <= num_segments; i++) { const float a = a_min + ((float)i / (float)num_segments) * (a_max - a_min); - _Path.push_back(ImVec2(centre.x + cosf(a) * radius, centre.y + sinf(a) * radius)); + _Path.push_back(ImVec2(centre.x + ImCos(a) * radius, centre.y + ImSin(a) * radius)); } } @@ -957,8 +965,8 @@ void ImDrawList::PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImV void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, int rounding_corners) { - rounding = ImMin(rounding, fabsf(b.x - a.x) * ( ((rounding_corners & ImDrawCornerFlags_Top) == ImDrawCornerFlags_Top) || ((rounding_corners & ImDrawCornerFlags_Bot) == ImDrawCornerFlags_Bot) ? 0.5f : 1.0f ) - 1.0f); - rounding = ImMin(rounding, fabsf(b.y - a.y) * ( ((rounding_corners & ImDrawCornerFlags_Left) == ImDrawCornerFlags_Left) || ((rounding_corners & ImDrawCornerFlags_Right) == ImDrawCornerFlags_Right) ? 0.5f : 1.0f ) - 1.0f); + rounding = ImMin(rounding, ImFabs(b.x - a.x) * ( ((rounding_corners & ImDrawCornerFlags_Top) == ImDrawCornerFlags_Top) || ((rounding_corners & ImDrawCornerFlags_Bot) == ImDrawCornerFlags_Bot) ? 0.5f : 1.0f ) - 1.0f); + rounding = ImMin(rounding, ImFabs(b.y - a.y) * ( ((rounding_corners & ImDrawCornerFlags_Left) == ImDrawCornerFlags_Left) || ((rounding_corners & ImDrawCornerFlags_Right) == ImDrawCornerFlags_Right) ? 0.5f : 1.0f ) - 1.0f); if (rounding <= 0.0f || rounding_corners == 0) { @@ -1543,7 +1551,7 @@ ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg_template) ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges) { - int data_size = 0; + size_t data_size = 0; void* data = ImFileLoadToMemory(filename, "rb", &data_size, 0); if (!data) { @@ -1558,7 +1566,7 @@ ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels, for (p = filename + strlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) {} ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "%s, %.0fpx", p, size_pixels); } - return AddFontFromMemoryTTF(data, data_size, size_pixels, &font_cfg, glyph_ranges); + return AddFontFromMemoryTTF(data, (int)data_size, size_pixels, &font_cfg, glyph_ranges); } // NB: Transfer ownership of 'ttf_data' to ImFontAtlas, unless font_cfg_template->FontDataOwnedByAtlas == false. Owned TTF buffer will be deleted after Build(). @@ -1640,6 +1648,7 @@ bool ImFontAtlas::GetMouseCursorTexData(ImGuiMouseCursor cursor_type, ImVec2* ou if (Flags & ImFontAtlasFlags_NoMouseCursors) return false; + IM_ASSERT(CustomRectIds[0] != -1); ImFontAtlas::CustomRect& r = CustomRects[CustomRectIds[0]]; IM_ASSERT(r.ID == FONT_ATLAS_DEFAULT_TEX_DATA_ID); ImVec2 pos = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][0] + ImVec2((float)r.X, (float)r.Y); @@ -1732,7 +1741,7 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == atlas)); const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo); - IM_ASSERT(font_offset >= 0); + IM_ASSERT(font_offset >= 0 && "FontData is incorrect, or FontNo cannot be found."); if (!stbtt_InitFont(&tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset)) { atlas->TexWidth = atlas->TexHeight = 0; // Reset output on failure @@ -1775,19 +1784,34 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) buf_packedchars_n += range.num_chars; } - // Pack + // Gather the sizes of all rectangle we need tmp.Rects = buf_rects + buf_rects_n; tmp.RectsCount = font_glyphs_count; buf_rects_n += font_glyphs_count; stbtt_PackSetOversampling(&spc, cfg.OversampleH, cfg.OversampleV); int n = stbtt_PackFontRangesGatherRects(&spc, &tmp.FontInfo, tmp.Ranges, tmp.RangesCount, tmp.Rects); IM_ASSERT(n == font_glyphs_count); + + // Detect missing glyphs and replace them with a zero-sized box instead of relying on the default glyphs + // This allows us merging overlapping icon fonts more easily. + int rect_i = 0; + for (int range_i = 0; range_i < tmp.RangesCount; range_i++) + for (int char_i = 0; char_i < tmp.Ranges[range_i].num_chars; char_i++, rect_i++) + if (stbtt_FindGlyphIndex(&tmp.FontInfo, tmp.Ranges[range_i].first_unicode_codepoint_in_range + char_i) == 0) + tmp.Rects[rect_i].w = tmp.Rects[rect_i].h = 0; + + // Pack stbrp_pack_rects((stbrp_context*)spc.pack_info, tmp.Rects, n); // Extend texture height + // Also mark missing glyphs as non-packed so we don't attempt to render into them for (int i = 0; i < n; i++) + { + if (tmp.Rects[i].w == 0 && tmp.Rects[i].h == 0) + tmp.Rects[i].was_packed = 0; if (tmp.Rects[i].was_packed) atlas->TexHeight = ImMax(atlas->TexHeight, tmp.Rects[i].y + tmp.Rects[i].h); + } } IM_ASSERT(buf_rects_n == total_glyphs_count); IM_ASSERT(buf_packedchars_n == total_glyphs_count); @@ -2352,7 +2376,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c } const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX[(int)c] : FallbackAdvanceX); - if (ImCharIsSpace(c)) + if (ImCharIsBlankW(c)) { if (inside_word) { @@ -2435,7 +2459,7 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons while (s < text_end) { const char c = *s; - if (ImCharIsSpace((unsigned int)c)) { s++; } else if (c == '\n') { s++; break; } else { break; } + if (ImCharIsBlankA(c)) { s++; } else if (c == '\n') { s++; break; } else { break; } } continue; } @@ -2560,7 +2584,7 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col while (s < text_end) { const char c = *s; - if (ImCharIsSpace((unsigned int)c)) { s++; } else if (c == '\n') { s++; break; } else { break; } + if (ImCharIsBlankA(c)) { s++; } else if (c == '\n') { s++; break; } else { break; } } continue; } @@ -2684,7 +2708,7 @@ static inline float ImAcos01(float x) { if (x <= 0.0f) return IM_PI * 0.5f; if (x >= 1.0f) return 0.0f; - return acosf(x); + return ImAcos(x); //return (-0.69813170079773212f * x * x - 0.87266462599716477f) * x + 1.5707963267948966f; // Cheap approximation, may be enough for what we do. } diff --git a/test/imgui_demo.cpp b/test/imgui_demo.cpp index 532020ac..126f4936 100755 --- a/test/imgui_demo.cpp +++ b/test/imgui_demo.cpp @@ -12,8 +12,7 @@ #include "sre/SDLRenderer.hpp" - -// dear imgui, v1.60 +// dear imgui, v1.61 // (demo code) // Message to the person tempted to delete this file when integrating ImGui into their code base: @@ -27,9 +26,9 @@ // Thank you, // -Your beloved friend, imgui_demo.cpp (that you won't delete) -// Message to beginner C/C++ programmers. About the meaning of 'static': in this demo code, we frequently we use 'static' variables inside functions. -// We do this as a way to gather code and data in the same place, just to make the demo code faster to read, faster to write, and use less code. -// A static variable persist across calls, so it is essentially like a global variable but declared inside the scope of the function. +// Message to beginner C/C++ programmers. About the meaning of 'static': in this demo code, we frequently we use 'static' variables inside functions. +// We do this as a way to gather code and data in the same place, just to make the demo code faster to read, faster to write, and use less code. +// A static variable persist across calls, so it is essentially like a global variable but declared inside the scope of the function. // It also happens to be a convenient way of storing simple UI related information as long as your function doesn't need to be reentrant or used in threads. // This might be a pattern you occasionally want to use in your code, but most of the real data you would be editing is likely to be stored outside your function. @@ -39,6 +38,7 @@ #include "imgui.h" #include // toupper, isprint +#include // INT_MIN, INT_MAX #include // sqrtf, powf, cosf, sinf, floorf, ceilf #include // vsnprintf, sscanf, printf #include // NULL, malloc, free, atoi @@ -97,7 +97,7 @@ 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 ShowExampleAppSimpleOverlay(bool* p_open); static void ShowExampleAppWindowTitles(bool* p_open); static void ShowExampleAppCustomRendering(bool* p_open); static void ShowExampleAppMainMenuBar(); @@ -150,7 +150,7 @@ void ImGui::ShowDemoWindow(bool* p_open) 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_simple_overlay = false; static bool show_app_window_titles = false; static bool show_app_custom_rendering = false; static bool show_app_style_editor = false; @@ -166,7 +166,7 @@ void ImGui::ShowDemoWindow(bool* p_open) 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_simple_overlay) ShowExampleAppSimpleOverlay(&show_app_simple_overlay); if (show_app_window_titles) ShowExampleAppWindowTitles(&show_app_window_titles); if (show_app_custom_rendering) ShowExampleAppCustomRendering(&show_app_custom_rendering); @@ -233,7 +233,7 @@ void ImGui::ShowDemoWindow(bool* p_open) 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("Simple overlay", NULL, &show_app_simple_overlay); ImGui::MenuItem("Manipulating window titles", NULL, &show_app_window_titles); ImGui::MenuItem("Custom rendering", NULL, &show_app_custom_rendering); ImGui::EndMenu(); @@ -351,18 +351,20 @@ void ImGui::ShowDemoWindow(bool* p_open) { static char str0[128] = "Hello, world!"; static int i0 = 123; - static float f0 = 0.001f; ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0)); ImGui::SameLine(); ShowHelpMarker("Hold SHIFT or use mouse to select text.\n" "CTRL+Left/Right to word jump.\n" "CTRL+A or double-click to select all.\n" "CTRL+X,CTRL+C,CTRL+V clipboard.\n" "CTRL+Z,CTRL+Y undo/redo.\n" "ESCAPE to revert.\n"); ImGui::InputInt("input int", &i0); ImGui::SameLine(); ShowHelpMarker("You can apply arithmetic operators +,*,/ on numerical values.\n e.g. [ 100 ], input \'*2\', result becomes [ 200 ]\nUse +- to subtract.\n"); + static float f0 = 0.001f; ImGui::InputFloat("input float", &f0, 0.01f, 1.0f); - // NB: You can use the %e notation as well. - static double d0 = 999999.000001; - ImGui::InputDouble("input double", &d0, 0.01f, 1.0f, "%.6f"); + static double d0 = 999999.00000001; + ImGui::InputDouble("input double", &d0, 0.01f, 1.0f, "%.8f"); + + static float f1 = 1.e10f; + ImGui::InputFloat("input scientific", &f1, 0.0f, 0.0f, "%e"); ImGui::SameLine(); ShowHelpMarker("You can input value using the scientific notation,\n e.g. \"1e+8\" becomes \"100000000\".\n"); static float vec4a[4] = { 0.10f, 0.20f, 0.30f, 0.44f }; @@ -374,7 +376,7 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::DragInt("drag int", &i1, 1); ImGui::SameLine(); ShowHelpMarker("Click and drag to edit value.\nHold SHIFT/ALT for faster/slower edit.\nDouble-click or CTRL+click to input value."); - ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%.0f%%"); + ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%d%%"); static float f1=1.00f, f2=0.0067f; ImGui::DragFloat("drag float", &f1, 0.005f); @@ -388,7 +390,7 @@ void ImGui::ShowDemoWindow(bool* p_open) static float f1=0.123f, f2=0.0f; ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f"); - ImGui::SliderFloat("slider log float", &f2, -10.0f, 10.0f, "%.4f", 3.0f); + ImGui::SliderFloat("slider float (curve)", &f2, -10.0f, 10.0f, "%.4f", 2.0f); static float angle = 0.0f; ImGui::SliderAngle("slider angle", &angle); } @@ -562,16 +564,18 @@ void ImGui::ShowDemoWindow(bool* p_open) if (ImGui::TreeNode("UTF-8 Text")) { // UTF-8 test with Japanese characters - // (needs a suitable font, try Arial Unicode or M+ fonts http://mplus-fonts.sourceforge.jp/mplus-outline-fonts/index-en.html) + // (Needs a suitable font, try Noto, or Arial Unicode, or M+ fonts. Read misc/fonts/README.txt for details.) // - From C++11 you can use the u8"my text" syntax to encode literal strings as UTF-8 // - For earlier compiler, you may be able to encode your sources as UTF-8 (e.g. Visual Studio save your file as 'UTF-8 without signature') - // - HOWEVER, FOR THIS DEMO FILE, BECAUSE WE WANT TO SUPPORT COMPILER, WE ARE *NOT* INCLUDING RAW UTF-8 CHARACTERS IN THIS SOURCE FILE. - // Instead we are encoding a few string with hexadecimal constants. Don't do this in your application! + // - FOR THIS DEMO FILE ONLY, BECAUSE WE WANT TO SUPPORT OLD COMPILERS, WE ARE *NOT* INCLUDING RAW UTF-8 CHARACTERS IN THIS SOURCE FILE. + // Instead we are encoding a few strings with hexadecimal constants. Don't do this in your application! + // Please use u8"text in any language" in your application! // Note that characters values are preserved even by InputText() if the font cannot be displayed, so you can safely copy & paste garbled characters into another application. - ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to load extra character ranges."); - ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)"); + ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to load extra character ranges. Read misc/fonts/README.txt for details."); + ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)"); // Normally we would use u8"blah blah" with the proper characters directly in the string. ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)"); - static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"; // "nihongo" + static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"; + //static char buf[32] = u8"NIHONGO"; // <- this is how you would write it with C++11, using real kanjis ImGui::InputText("UTF-8 input", buf, IM_ARRAYSIZE(buf)); ImGui::TreePop(); } @@ -802,7 +806,7 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::TreePop(); } - if (ImGui::TreeNode("Plots widgets")) + if (ImGui::TreeNode("Plots Widgets")) { static bool animate = true; ImGui::Checkbox("Animate", &animate); @@ -993,13 +997,12 @@ void ImGui::ShowDemoWindow(bool* p_open) if (inputs_mode == 4) flags |= ImGuiColorEditFlags_HEX; ImGui::ColorPicker4("MyColor##4", (float*)&color, flags, ref_color ? &ref_color_v.x : NULL); - ImGui::Text("Programmatically set defaults/options:"); + ImGui::Text("Programmatically set defaults:"); ImGui::SameLine(); ShowHelpMarker("SetColorEditOptions() is designed to allow you to set boot-time default.\nWe don't have Push/Pop functions because you can force options on a per-widget basis if needed, and the user can change non-forced ones with the options menu.\nWe don't have a getter to avoid encouraging you to persistently save values that aren't forward-compatible."); - if (ImGui::Button("Uint8 + HSV")) - ImGui::SetColorEditOptions(ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_HSV); - ImGui::SameLine(); - if (ImGui::Button("Float + HDR")) - ImGui::SetColorEditOptions(ImGuiColorEditFlags_Float | ImGuiColorEditFlags_RGB); + if (ImGui::Button("Default: Uint8 + HSV + Hue Bar")) + ImGui::SetColorEditOptions(ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_PickerHueBar); + if (ImGui::Button("Default: Float + HDR + Hue Wheel")) + ImGui::SetColorEditOptions(ImGuiColorEditFlags_Float | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_PickerHueWheel); ImGui::TreePop(); } @@ -1009,7 +1012,80 @@ void ImGui::ShowDemoWindow(bool* p_open) static float begin = 10, end = 90; static int begin_i = 100, end_i = 1000; ImGui::DragFloatRange2("range", &begin, &end, 0.25f, 0.0f, 100.0f, "Min: %.1f %%", "Max: %.1f %%"); - ImGui::DragIntRange2("range int (no bounds)", &begin_i, &end_i, 5, 0, 0, "Min: %.0f units", "Max: %.0f units"); + ImGui::DragIntRange2("range int (no bounds)", &begin_i, &end_i, 5, 0, 0, "Min: %d units", "Max: %d units"); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Data Types")) + { + // The DragScalar, InputScalar, SliderScalar functions allow manipulating most common data types: signed/unsigned int/long long and float/double + // To avoid polluting the public API with all possible combinations, we use the ImGuiDataType enum to pass the type, and argument-by-values are turned into argument-by-address. + // This is the reason the test code below creates local variables to hold "zero" "one" etc. for each types. + // In practice, if you frequently use a given type that is not covered by the normal API entry points, you may want to wrap it yourself inside a 1 line function + // which can take typed values argument instead of void*, and then pass their address to the generic function. For example: + // bool SliderU64(const char *label, u64* value, u64 min = 0, u64 max = 0, const char* format = "%lld") { return SliderScalar(label, ImGuiDataType_U64, value, &min, &max, format); } + // Below are helper variables we can take the address of to work-around this: + // Note that the SliderScalar function has a maximum usable range of half the natural type maximum, hence the /2 below. + const ImS32 s32_zero = 0, s32_one = 1, s32_fifty = 50, s32_min = INT_MIN/2, s32_max = INT_MAX/2, s32_hi_a = INT_MAX/2 - 100, s32_hi_b = INT_MAX/2; + const ImU32 u32_zero = 0, u32_one = 1, u32_fifty = 50, u32_min = 0, u32_max = UINT_MAX/2, u32_hi_a = UINT_MAX/2 - 100, u32_hi_b = UINT_MAX/2; + const ImS64 s64_zero = 0, s64_one = 1, s64_fifty = 50, s64_min = LLONG_MIN/2, s64_max = LLONG_MAX/2, s64_hi_a = LLONG_MAX/2 - 100, s64_hi_b = LLONG_MAX/2; + const ImU64 u64_zero = 0, u64_one = 1, u64_fifty = 50, u64_min = 0, u64_max = ULLONG_MAX/2, u64_hi_a = ULLONG_MAX/2 - 100, u64_hi_b = ULLONG_MAX/2; + const float f32_zero = 0.f, f32_one = 1.f, f32_lo_a = -10000000000.0f, f32_hi_a = +10000000000.0f; + const double f64_zero = 0., f64_one = 1., f64_lo_a = -1000000000000000, f64_hi_a = +1000000000000000; + + // State + static ImS32 s32_v = -1; + static ImU32 u32_v = (ImU32)-1; + static ImS64 s64_v = -1; + static ImU64 u64_v = (ImU64)-1; + static float f32_v = 0.123f; + static double f64_v = 90000.01234567890123456789; + + const float drag_speed = 0.2f; + static bool drag_clamp = false; + ImGui::Text("Drags:"); + ImGui::Checkbox("Clamp integers to 0..50", &drag_clamp); ImGui::SameLine(); ShowHelpMarker("As with every widgets in dear imgui, we never modify values unless there is a user interaction.\nYou can override the clamping limits by using CTRL+Click to input a value."); + ImGui::DragScalar("drag s32", ImGuiDataType_S32, &s32_v, drag_speed, drag_clamp ? &s32_zero : NULL, drag_clamp ? &s32_fifty : NULL); + ImGui::DragScalar("drag u32", ImGuiDataType_U32, &u32_v, drag_speed, drag_clamp ? &u32_zero : NULL, drag_clamp ? &u32_fifty : NULL, "%u ms"); + ImGui::DragScalar("drag s64", ImGuiDataType_S64, &s64_v, drag_speed, drag_clamp ? &s64_zero : NULL, drag_clamp ? &s64_fifty : NULL); + ImGui::DragScalar("drag u64", ImGuiDataType_U64, &u64_v, drag_speed, drag_clamp ? &u64_zero : NULL, drag_clamp ? &u64_fifty : NULL); + ImGui::DragScalar("drag float", ImGuiDataType_Float, &f32_v, 0.005f, &f32_zero, &f32_one, "%f", 1.0f); + ImGui::DragScalar("drag float ^2", ImGuiDataType_Float, &f32_v, 0.005f, &f32_zero, &f32_one, "%f", 2.0f); ImGui::SameLine(); ShowHelpMarker("You can use the 'power' parameter to increase tweaking precision on one side of the range."); + ImGui::DragScalar("drag double", ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, NULL, "%.10f grams", 1.0f); + ImGui::DragScalar("drag double ^2", ImGuiDataType_Double, &f64_v, 0.0005f, &f64_zero, &f64_one, "0 < %.10f < 1", 2.0f); + + ImGui::Text("Sliders"); + ImGui::SliderScalar("slider s32 low", ImGuiDataType_S32, &s32_v, &s32_zero, &s32_fifty,"%d"); + ImGui::SliderScalar("slider s32 high", ImGuiDataType_S32, &s32_v, &s32_hi_a, &s32_hi_b, "%d"); + ImGui::SliderScalar("slider s32 full", ImGuiDataType_S32, &s32_v, &s32_min, &s32_max, "%d"); + ImGui::SliderScalar("slider u32 low", ImGuiDataType_U32, &u32_v, &u32_zero, &u32_fifty,"%u"); + ImGui::SliderScalar("slider u32 high", ImGuiDataType_U32, &u32_v, &u32_hi_a, &u32_hi_b, "%u"); + ImGui::SliderScalar("slider u32 full", ImGuiDataType_U32, &u32_v, &u32_min, &u32_max, "%u"); + ImGui::SliderScalar("slider s64 low", ImGuiDataType_S64, &s64_v, &s64_zero, &s64_fifty,"%I64d"); + ImGui::SliderScalar("slider s64 high", ImGuiDataType_S64, &s64_v, &s64_hi_a, &s64_hi_b, "%I64d"); + ImGui::SliderScalar("slider s64 full", ImGuiDataType_S64, &s64_v, &s64_min, &s64_max, "%I64d"); + ImGui::SliderScalar("slider u64 low", ImGuiDataType_U64, &u64_v, &u64_zero, &u64_fifty,"%I64u ms"); + ImGui::SliderScalar("slider u64 high", ImGuiDataType_U64, &u64_v, &u64_hi_a, &u64_hi_b, "%I64u ms"); + ImGui::SliderScalar("slider u64 full", ImGuiDataType_U64, &u64_v, &u64_min, &u64_max, "%I64u ms"); + ImGui::SliderScalar("slider float low", ImGuiDataType_Float, &f32_v, &f32_zero, &f32_one); + ImGui::SliderScalar("slider float low^2", ImGuiDataType_Float, &f32_v, &f32_zero, &f32_one, "%.10f", 2.0f); + ImGui::SliderScalar("slider float high", ImGuiDataType_Float, &f32_v, &f32_lo_a, &f32_hi_a, "%e"); + ImGui::SliderScalar("slider double low", ImGuiDataType_Double, &f64_v, &f64_zero, &f64_one, "%.10f grams", 1.0f); + ImGui::SliderScalar("slider double low^2",ImGuiDataType_Double, &f64_v, &f64_zero, &f64_one, "%.10f", 2.0f); + ImGui::SliderScalar("slider double high", ImGuiDataType_Double, &f64_v, &f64_lo_a, &f64_hi_a, "%e grams", 1.0f); + + static bool inputs_step = true; + ImGui::Text("Inputs"); + ImGui::Checkbox("Show step buttons", &inputs_step); + ImGui::InputScalar("input s32", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%d"); + ImGui::InputScalar("input s32 hex", ImGuiDataType_S32, &s32_v, inputs_step ? &s32_one : NULL, NULL, "%08X", ImGuiInputTextFlags_CharsHexadecimal); + ImGui::InputScalar("input u32", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%u"); + ImGui::InputScalar("input u32 hex", ImGuiDataType_U32, &u32_v, inputs_step ? &u32_one : NULL, NULL, "%08X", ImGuiInputTextFlags_CharsHexadecimal); + ImGui::InputScalar("input s64", ImGuiDataType_S64, &s64_v, inputs_step ? &s64_one : NULL); + ImGui::InputScalar("input u64", ImGuiDataType_U64, &u64_v, inputs_step ? &u64_one : NULL); + ImGui::InputScalar("input float", ImGuiDataType_Float, &f32_v, inputs_step ? &f32_one : NULL); + ImGui::InputScalar("input double", ImGuiDataType_Double, &f64_v, inputs_step ? &f64_one : NULL); + ImGui::TreePop(); } @@ -1021,16 +1097,16 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::InputFloat2("input float2", vec4f); ImGui::DragFloat2("drag float2", vec4f, 0.01f, 0.0f, 1.0f); ImGui::SliderFloat2("slider float2", vec4f, 0.0f, 1.0f); - ImGui::DragInt2("drag int2", vec4i, 1, 0, 255); ImGui::InputInt2("input int2", vec4i); + ImGui::DragInt2("drag int2", vec4i, 1, 0, 255); ImGui::SliderInt2("slider int2", vec4i, 0, 255); ImGui::Spacing(); ImGui::InputFloat3("input float3", vec4f); ImGui::DragFloat3("drag float3", vec4f, 0.01f, 0.0f, 1.0f); ImGui::SliderFloat3("slider float3", vec4f, 0.0f, 1.0f); - ImGui::DragInt3("drag int3", vec4i, 1, 0, 255); ImGui::InputInt3("input int3", vec4i); + ImGui::DragInt3("drag int3", vec4i, 1, 0, 255); ImGui::SliderInt3("slider int3", vec4i, 0, 255); ImGui::Spacing(); @@ -1312,10 +1388,12 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::Button("LEVERAGE\nBUZZWORD", size); ImGui::SameLine(); - ImGui::ListBoxHeader("List", size); - ImGui::Selectable("Selected", true); - ImGui::Selectable("Not Selected", false); - ImGui::ListBoxFooter(); + if (ImGui::ListBoxHeader("List", size)) + { + ImGui::Selectable("Selected", true); + ImGui::Selectable("Not Selected", false); + ImGui::ListBoxFooter(); + } ImGui::TreePop(); } @@ -1382,9 +1460,9 @@ void ImGui::ShowDemoWindow(bool* p_open) static int track_line = 50, scroll_to_px = 200; ImGui::Checkbox("Track", &track); ImGui::PushItemWidth(100); - ImGui::SameLine(130); track |= ImGui::DragInt("##line", &track_line, 0.25f, 0, 99, "Line = %.0f"); + ImGui::SameLine(130); track |= ImGui::DragInt("##line", &track_line, 0.25f, 0, 99, "Line = %d"); bool scroll_to = ImGui::Button("Scroll To Pos"); - ImGui::SameLine(130); scroll_to |= ImGui::DragInt("##pos_y", &scroll_to_px, 1.00f, 0, 9999, "Y = %.0f px"); + ImGui::SameLine(130); scroll_to |= ImGui::DragInt("##pos_y", &scroll_to_px, 1.00f, 0, 9999, "Y = %d px"); ImGui::PopItemWidth(); if (scroll_to) track = false; @@ -1427,7 +1505,7 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::BeginChild("scrolling", ImVec2(0, ImGui::GetFrameHeightWithSpacing()*7 + 30), true, ImGuiWindowFlags_HorizontalScrollbar); for (int line = 0; line < lines; line++) { - // Display random stuff (for the sake of this trivial demo we are using basic Button+SameLine. If you want to create your own time line for a real application you may be better off + // Display random stuff (for the sake of this trivial demo we are using basic Button+SameLine. If you want to create your own time line for a real application you may be better off // manipulating the cursor position yourself, aka using SetCursorPos/SetCursorScreenPos to position the widgets yourself. You may also want to use the lower-level ImDrawList API) int num_buttons = 10 + ((line & 1) ? line * 9 : line * 3); for (int n = 0; n < num_buttons; n++) @@ -1721,14 +1799,14 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::Text("ImGui"); ImGui::Button("Apple"); static float foo = 1.0f; - ImGui::InputFloat("red", &foo, 0.05f, 0, 3); + ImGui::InputFloat("red", &foo, 0.05f, 0, "%.3f"); ImGui::Text("An extra line here."); ImGui::NextColumn(); ImGui::Text("Sailor"); ImGui::Button("Corniflower"); static float bar = 1.0f; - ImGui::InputFloat("blue", &bar, 0.05f, 0, 3); + ImGui::InputFloat("blue", &bar, 0.05f, 0, "%.3f"); ImGui::NextColumn(); if (ImGui::CollapsingHeader("Category A")) { ImGui::Text("Blah blah blah"); } ImGui::NextColumn(); @@ -1867,8 +1945,8 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor); ImGui::SameLine(); ShowHelpMarker("Instruct ImGui to render a mouse cursor for you in software. 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::CheckboxFlags("io.ConfigFlags: NavEnableGamepad", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad); - ImGui::CheckboxFlags("io.ConfigFlags: NavEnableKeyboard", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard); + ImGui::CheckboxFlags("io.ConfigFlags: NavEnableGamepad [beta]", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad); + ImGui::CheckboxFlags("io.ConfigFlags: NavEnableKeyboard [beta]", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard); ImGui::CheckboxFlags("io.ConfigFlags: NavEnableSetMousePos", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableSetMousePos); ImGui::SameLine(); ShowHelpMarker("Instruct navigation to move the mouse cursor. See comment for ImGuiConfigFlags_NavEnableSetMousePos."); ImGui::CheckboxFlags("io.ConfigFlags: NoMouseCursorChange", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange); @@ -1880,6 +1958,7 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::Text("Mouse pos: (%g, %g)", io.MousePos.x, io.MousePos.y); else ImGui::Text("Mouse pos: "); + 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 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 dbl-clicked:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseDoubleClicked(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } @@ -2184,6 +2263,8 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::Text("Alignment"); ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f"); ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); ShowHelpMarker("Alignment applies when a button is larger than its text content."); + ImGui::Text("Safe Area Padding"); ImGui::SameLine(); ShowHelpMarker("Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured)."); + ImGui::SliderFloat2("DisplaySafeAreaPadding", (float*)&style.DisplaySafeAreaPadding, 0.0f, 30.0f, "%.0f"); ImGui::TreePop(); } @@ -2296,7 +2377,8 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImVec2 cell_p2(cell_p1.x + cell_size, cell_p1.y + cell_size); const ImFontGlyph* glyph = font->FindGlyphNoFallback((ImWchar)(base+n)); draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255,255,255,100) : IM_COL32(255,255,255,50)); - font->RenderChar(draw_list, cell_size, cell_p1, ImGui::GetColorU32(ImGuiCol_Text), (ImWchar)(base+n)); // We use ImFont::RenderChar as a shortcut because we don't have UTF-8 conversion functions available to generate a string. + if (glyph) + font->RenderChar(draw_list, cell_size, cell_p1, ImGui::GetColorU32(ImGuiCol_Text), (ImWchar)(base+n)); // We use ImFont::RenderChar as a shortcut because we don't have UTF-8 conversion functions available to generate a string. if (glyph && ImGui::IsMouseHoveringRect(cell_p1, cell_p2)) { ImGui::BeginTooltip(); @@ -2483,21 +2565,26 @@ static void ShowExampleAppConstrainedResize(bool* p_open) } // Demonstrate creating a simple static window with no decoration + a context-menu to choose which corner of the screen to use. -static void ShowExampleAppFixedOverlay(bool* p_open) +static void ShowExampleAppSimpleOverlay(bool* p_open) { const float DISTANCE = 10.0f; static int corner = 0; ImVec2 window_pos = ImVec2((corner & 1) ? ImGui::GetIO().DisplaySize.x - DISTANCE : DISTANCE, (corner & 2) ? ImGui::GetIO().DisplaySize.y - DISTANCE : DISTANCE); ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f); - ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot); + if (corner != -1) + ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot); ImGui::SetNextWindowBgAlpha(0.3f); // Transparent background - if (ImGui::Begin("Example: Fixed Overlay", p_open, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_NoFocusOnAppearing|ImGuiWindowFlags_NoNav)) + if (ImGui::Begin("Example: Simple Overlay", p_open, (corner != -1 ? ImGuiWindowFlags_NoMove : 0) | ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_NoFocusOnAppearing|ImGuiWindowFlags_NoNav)) { - ImGui::Text("Simple overlay\nin the corner of the screen.\n(right-click to change position)"); + ImGui::Text("Simple overlay\n" "in the corner of the screen.\n" "(right-click to change position)"); ImGui::Separator(); - ImGui::Text("Mouse Position: (%.1f,%.1f)", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y); + if (ImGui::IsMousePosValid()) + ImGui::Text("Mouse Position: (%.1f,%.1f)", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y); + else + ImGui::Text("Mouse Position: "); if (ImGui::BeginPopupContextWindow()) { + if (ImGui::MenuItem("Custom", NULL, corner == -1)) corner = -1; if (ImGui::MenuItem("Top-left", NULL, corner == 0)) corner = 0; if (ImGui::MenuItem("Top-right", NULL, corner == 1)) corner = 1; if (ImGui::MenuItem("Bottom-left", NULL, corner == 2)) corner = 2; @@ -2536,7 +2623,7 @@ static void ShowExampleAppWindowTitles(bool*) ImGui::End(); } -// Demonstrate using the low-level ImDrawList to draw custom shapes. +// Demonstrate using the low-level ImDrawList to draw custom shapes. static void ShowExampleAppCustomRendering(bool* p_open) { ImGui::SetNextWindowSize(ImVec2(350,560), ImGuiCond_FirstUseEver); @@ -2555,8 +2642,10 @@ static void ShowExampleAppCustomRendering(bool* p_open) // Primitives ImGui::Text("Primitives"); static float sz = 36.0f; + static float thickness = 4.0f; static ImVec4 col = ImVec4(1.0f,1.0f,0.4f,1.0f); ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 72.0f, "%.0f"); + ImGui::DragFloat("Thickness", &thickness, 0.05f, 1.0f, 8.0f, "%.02f"); ImGui::ColorEdit3("Color", &col.x); { const ImVec2 p = ImGui::GetCursorScreenPos(); @@ -2564,16 +2653,16 @@ static void ShowExampleAppCustomRendering(bool* p_open) float x = p.x + 4.0f, y = p.y + 4.0f, spacing = 8.0f; for (int n = 0; n < 2; n++) { - float thickness = (n == 0) ? 1.0f : 4.0f; - draw_list->AddCircle(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 20, thickness); x += sz+spacing; - draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 0.0f, ImDrawCornerFlags_All, thickness); x += sz+spacing; - draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_All, thickness); x += sz+spacing; - draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_TopLeft|ImDrawCornerFlags_BotRight, thickness); x += sz+spacing; - draw_list->AddTriangle(ImVec2(x+sz*0.5f, y), ImVec2(x+sz,y+sz-0.5f), ImVec2(x,y+sz-0.5f), col32, thickness); x += sz+spacing; - draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y ), col32, thickness); x += sz+spacing; - draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, thickness); x += sz+spacing; - draw_list->AddLine(ImVec2(x, y), ImVec2(x, y+sz), col32, thickness); x += spacing; - draw_list->AddBezierCurve(ImVec2(x, y), ImVec2(x+sz*1.3f,y+sz*0.3f), ImVec2(x+sz-sz*1.3f,y+sz-sz*0.3f), ImVec2(x+sz, y+sz), col32, thickness); + float curr_thickness = (n == 0) ? 1.0f : thickness; + draw_list->AddCircle(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 20, curr_thickness); x += sz+spacing; + draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 0.0f, ImDrawCornerFlags_All, curr_thickness); x += sz+spacing; + draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_All, curr_thickness); x += sz+spacing; + draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_TopLeft|ImDrawCornerFlags_BotRight, curr_thickness); x += sz+spacing; + draw_list->AddTriangle(ImVec2(x+sz*0.5f, y), ImVec2(x+sz,y+sz-0.5f), ImVec2(x,y+sz-0.5f), col32, curr_thickness); x += sz+spacing; + draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y ), col32, curr_thickness); x += sz+spacing; // Horizontal line (note: drawing a filled rectangle will be faster!) + draw_list->AddLine(ImVec2(x, y), ImVec2(x, y+sz), col32, curr_thickness); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!) + draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, curr_thickness); x += sz+spacing; // Diagonal line + draw_list->AddBezierCurve(ImVec2(x, y), ImVec2(x+sz*1.3f,y+sz*0.3f), ImVec2(x+sz-sz*1.3f,y+sz-sz*0.3f), ImVec2(x+sz, y+sz), col32, curr_thickness); x = p.x + 4; y += sz+spacing; } @@ -2582,6 +2671,9 @@ static void ShowExampleAppCustomRendering(bool* p_open) draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f); x += sz+spacing; draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_TopLeft|ImDrawCornerFlags_BotRight); x += sz+spacing; draw_list->AddTriangleFilled(ImVec2(x+sz*0.5f, y), ImVec2(x+sz,y+sz-0.5f), ImVec2(x,y+sz-0.5f), col32); x += sz+spacing; + draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+thickness), col32); x += sz+spacing; // Horizontal line (faster than AddLine, but only handle integer thickness) + draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+thickness, y+sz), col32); x += spacing+spacing; // Vertical line (faster than AddLine, but only handle integer thickness) + draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+1, y+1), col32); x += sz; // Pixel (faster than AddLine) draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x+sz, y+sz), IM_COL32(0,0,0,255), IM_COL32(255,0,0,255), IM_COL32(255,255,0,255), IM_COL32(0,255,0,255)); ImGui::Dummy(ImVec2((sz+spacing)*8, (sz+spacing)*3)); } @@ -2595,7 +2687,7 @@ static void ShowExampleAppCustomRendering(bool* p_open) ImGui::Text("Left-click and drag to add lines,\nRight-click to undo"); // Here we are using InvisibleButton() as a convenience to 1) advance the cursor and 2) allows us to use IsItemHovered() - // However you can draw directly and poll mouse/keyboard by yourself. You can manipulate the cursor using GetCursorPos() and SetCursorPos(). + // But you can also draw directly and poll mouse/keyboard by yourself. You can manipulate the cursor using GetCursorPos() and SetCursorPos(). // If you only use the ImDrawList API, you can notify the owner window of its extends by using SetCursorPos(max). ImVec2 canvas_pos = ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates! ImVec2 canvas_size = ImGui::GetContentRegionAvail(); // Resize canvas to what's available @@ -2658,7 +2750,7 @@ struct ExampleAppConsole Commands.push_back("HISTORY"); Commands.push_back("CLEAR"); Commands.push_back("CLASSIFY"); // "classify" is here to provide an example of "C"+[tab] completing to "CL" and displaying matches. - AddLog("Welcome to ImGui!"); + AddLog("Welcome to Dear ImGui!"); } ~ExampleAppConsole() { @@ -2671,6 +2763,7 @@ struct ExampleAppConsole static int Stricmp(const char* str1, const char* str2) { int d; while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; } return d; } static int Strnicmp(const char* str1, const char* str2, int n) { int d = 0; while (n > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; n--; } return d; } static char* Strdup(const char *str) { size_t len = strlen(str) + 1; void* buff = malloc(len); return (char*)memcpy(buff, (const void*)str, len); } + static void Strtrim(char* str) { char* str_end = str + strlen(str); while (str_end > str && str_end[-1] == ' ') str_end--; *str_end = 0; } void ClearLog() { @@ -2746,7 +2839,7 @@ struct ExampleAppConsole // 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. + // However, 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. @@ -2769,7 +2862,7 @@ struct ExampleAppConsole if (copy_to_clipboard) ImGui::LogFinish(); if (ScrollToBottom) - ImGui::SetScrollHere(); + ImGui::SetScrollHere(1.0f); ScrollToBottom = false; ImGui::PopStyleVar(); ImGui::EndChild(); @@ -2779,8 +2872,7 @@ struct ExampleAppConsole bool reclaim_focus = false; if (ImGui::InputText("Input", InputBuf, IM_ARRAYSIZE(InputBuf), ImGuiInputTextFlags_EnterReturnsTrue|ImGuiInputTextFlags_CallbackCompletion|ImGuiInputTextFlags_CallbackHistory, &TextEditCallbackStub, (void*)this)) { - char* input_end = InputBuf+strlen(InputBuf); - while (input_end > InputBuf && input_end[-1] == ' ') { input_end--; } *input_end = 0; + Strtrim(InputBuf); if (InputBuf[0]) ExecCommand(InputBuf); strcpy(InputBuf, ""); From 767f96e003de018a865eb286ba30eb05088cb2a3 Mon Sep 17 00:00:00 2001 From: Morten Nobel-Joergensen Date: Sat, 19 May 2018 23:09:13 +0200 Subject: [PATCH 05/22] Travis : Compile tests --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b902767b..0c49cb5d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,4 +15,4 @@ addons: script: - CXX=/usr/bin/g++-5 CC=/usr/bin/gcc-5 cmake . - - cmake --build . -- -j2 \ No newline at end of file + - cmake --build . -- -j2 -D USE_SRE_TEST_AND_UTILS=ON \ No newline at end of file From 78f94fbbfdfb3c1bcaf05a7a9d814a0a304fc58f Mon Sep 17 00:00:00 2001 From: Morten Nobel-Joergensen Date: Sat, 19 May 2018 23:13:25 +0200 Subject: [PATCH 06/22] Travis : Compile tests --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0c49cb5d..dac8bb08 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,5 +14,5 @@ addons: - libsdl2-image-dev script: - - CXX=/usr/bin/g++-5 CC=/usr/bin/gcc-5 cmake . - - cmake --build . -- -j2 -D USE_SRE_TEST_AND_UTILS=ON \ No newline at end of file + - CXX=/usr/bin/g++-5 CC=/usr/bin/gcc-5 cmake . -D USE_SRE_TEST_AND_UTILS=ON + - cmake --build . -- -j2 \ No newline at end of file From ef5703526cb8225c3ed1574f27f48ff54600b790 Mon Sep 17 00:00:00 2001 From: Morten Nobel-Joergensen Date: Sat, 19 May 2018 23:16:34 +0200 Subject: [PATCH 07/22] Travis : Compile tests --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index dac8bb08..b902767b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,5 +14,5 @@ addons: - libsdl2-image-dev script: - - CXX=/usr/bin/g++-5 CC=/usr/bin/gcc-5 cmake . -D USE_SRE_TEST_AND_UTILS=ON + - CXX=/usr/bin/g++-5 CC=/usr/bin/gcc-5 cmake . - cmake --build . -- -j2 \ No newline at end of file From 86f5677de2e1bb78579628bcc3a9ad928396f8dc Mon Sep 17 00:00:00 2001 From: Morten Nobel-Joergensen Date: Sat, 19 May 2018 23:18:18 +0200 Subject: [PATCH 08/22] Travis : Compile tests --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b902767b..3b242479 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,5 +14,5 @@ addons: - libsdl2-image-dev script: - - CXX=/usr/bin/g++-5 CC=/usr/bin/gcc-5 cmake . + - CXX=/usr/bin/g++-5 CC=/usr/bin/gcc-5 cmake -DUSE_SRE_TEST_AND_UTILS=ON . - cmake --build . -- -j2 \ No newline at end of file From 26bfcb51f307e8609fc8ac8d2c5d4e141644c5c6 Mon Sep 17 00:00:00 2001 From: Morten Nobel-Joergensen Date: Sat, 2 Jun 2018 11:16:29 +0200 Subject: [PATCH 09/22] Add git submodules to glm, imgui and picojson --- .gitmodules | 9 + CMakeLists.txt | 3 + examples/02_spheres.cpp | 1 + examples/03_spinning-cube.cpp | 2 +- examples/04_spinning-primitives-tex.cpp | 1 + examples/05_obj-viewer.cpp | 1 + examples/06_custom-mesh-layout.cpp | 1 + examples/07_matcap.cpp | 1 + examples/08_gui.cpp | 1 + examples/09_picking.cpp | 1 + examples/10_skybox-example.cpp | 2 +- examples/11_sprite-example.cpp | 2 +- examples/12_render-to-texture.cpp | 1 + examples/13_benchmark64k.cpp | 1 + examples/14_spinning-primitives-openvr.cpp | 1 + examples/15_cloth_simulation.cpp | 2 +- examples/16_shadows.cpp | 1 + examples/CMakeLists.txt | 2 +- include/glm/CMakeLists.txt | 67 - include/glm/common.hpp | 6 - include/glm/detail/_features.hpp | 399 - include/glm/detail/_fixes.hpp | 30 - include/glm/detail/_noise.hpp | 107 - include/glm/detail/_swizzle.hpp | 797 - include/glm/detail/_swizzle_func.hpp | 696 - include/glm/detail/_vectorize.hpp | 131 - include/glm/detail/dummy.cpp | 207 - include/glm/detail/func_common.hpp | 427 - include/glm/detail/func_common.inl | 849 - include/glm/detail/func_common_simd.inl | 231 - include/glm/detail/func_exponential.hpp | 103 - include/glm/detail/func_exponential.inl | 146 - include/glm/detail/func_exponential_simd.inl | 35 - include/glm/detail/func_geometric.hpp | 113 - include/glm/detail/func_geometric.inl | 247 - include/glm/detail/func_geometric_simd.inl | 99 - include/glm/detail/func_integer.hpp | 203 - include/glm/detail/func_integer.inl | 368 - include/glm/detail/func_integer_simd.inl | 68 - include/glm/detail/func_matrix.hpp | 149 - include/glm/detail/func_matrix.inl | 401 - include/glm/detail/func_matrix_simd.inl | 88 - include/glm/detail/func_packing.hpp | 168 - include/glm/detail/func_packing.inl | 190 - include/glm/detail/func_packing_simd.inl | 9 - include/glm/detail/func_trigonometric.hpp | 176 - include/glm/detail/func_trigonometric.inl | 200 - .../glm/detail/func_trigonometric_simd.inl | 0 include/glm/detail/func_vector_relational.hpp | 111 - include/glm/detail/func_vector_relational.inl | 105 - .../detail/func_vector_relational_simd.inl | 9 - include/glm/detail/glm.cpp | 257 - include/glm/detail/precision.hpp | 63 - include/glm/detail/setup.hpp | 828 - include/glm/detail/type_float.hpp | 67 - include/glm/detail/type_gentype.hpp | 195 - include/glm/detail/type_gentype.inl | 341 - include/glm/detail/type_half.hpp | 19 - include/glm/detail/type_half.inl | 244 - include/glm/detail/type_int.hpp | 306 - include/glm/detail/type_mat.hpp | 767 - include/glm/detail/type_mat.inl | 3 - include/glm/detail/type_mat2x2.hpp | 183 - include/glm/detail/type_mat2x2.inl | 484 - include/glm/detail/type_mat2x3.hpp | 165 - include/glm/detail/type_mat2x3.inl | 458 - include/glm/detail/type_mat2x4.hpp | 167 - include/glm/detail/type_mat2x4.inl | 467 - include/glm/detail/type_mat3x2.hpp | 173 - include/glm/detail/type_mat3x2.inl | 492 - include/glm/detail/type_mat3x3.hpp | 190 - include/glm/detail/type_mat3x3.inl | 561 - include/glm/detail/type_mat3x4.hpp | 172 - include/glm/detail/type_mat3x4.inl | 532 - include/glm/detail/type_mat4x2.hpp | 177 - include/glm/detail/type_mat4x2.inl | 545 - include/glm/detail/type_mat4x3.hpp | 177 - include/glm/detail/type_mat4x3.inl | 562 - include/glm/detail/type_mat4x4.hpp | 195 - include/glm/detail/type_mat4x4.inl | 671 - include/glm/detail/type_mat4x4_simd.inl | 7 - include/glm/detail/type_vec.hpp | 576 - include/glm/detail/type_vec.inl | 2 - include/glm/detail/type_vec1.hpp | 302 - include/glm/detail/type_vec1.inl | 558 - include/glm/detail/type_vec2.hpp | 388 - include/glm/detail/type_vec2.inl | 894 - include/glm/detail/type_vec3.hpp | 409 - include/glm/detail/type_vec3.inl | 1022 -- include/glm/detail/type_vec4.hpp | 454 - include/glm/detail/type_vec4.inl | 969 -- include/glm/detail/type_vec4_simd.inl | 481 - include/glm/exponential.hpp | 6 - include/glm/ext.hpp | 119 - include/glm/fwd.hpp | 2570 --- include/glm/geometric.hpp | 6 - include/glm/glm.hpp | 88 - include/glm/gtc/bitfield.hpp | 207 - include/glm/gtc/bitfield.inl | 515 - include/glm/gtc/color_encoding.inl | 65 - include/glm/gtc/color_space.hpp | 56 - include/glm/gtc/color_space.inl | 75 - include/glm/gtc/constants.hpp | 176 - include/glm/gtc/constants.inl | 181 - include/glm/gtc/epsilon.hpp | 73 - include/glm/gtc/epsilon.inl | 125 - include/glm/gtc/functions.hpp | 53 - include/glm/gtc/functions.inl | 31 - include/glm/gtc/integer.hpp | 102 - include/glm/gtc/integer.inl | 71 - include/glm/gtc/matrix_access.hpp | 59 - include/glm/gtc/matrix_access.inl | 63 - include/glm/gtc/matrix_integer.hpp | 486 - include/glm/gtc/matrix_inverse.hpp | 49 - include/glm/gtc/matrix_inverse.inl | 120 - include/glm/gtc/matrix_transform.hpp | 465 - include/glm/gtc/matrix_transform.inl | 575 - include/glm/gtc/noise.hpp | 60 - include/glm/gtc/noise.inl | 808 - include/glm/gtc/packing.hpp | 579 - include/glm/gtc/packing.inl | 781 - include/glm/gtc/quaternion.hpp | 397 - include/glm/gtc/quaternion.inl | 795 - include/glm/gtc/quaternion_simd.inl | 198 - include/glm/gtc/random.hpp | 98 - include/glm/gtc/random.inl | 350 - include/glm/gtc/reciprocal.hpp | 135 - include/glm/gtc/reciprocal.inl | 192 - include/glm/gtc/round.hpp | 174 - include/glm/gtc/round.inl | 344 - include/glm/gtc/type_aligned.hpp | 362 - include/glm/gtc/type_precision.hpp | 861 - include/glm/gtc/type_precision.inl | 7 - include/glm/gtc/type_ptr.hpp | 149 - include/glm/gtc/type_ptr.inl | 450 - include/glm/gtc/ulp.hpp | 63 - include/glm/gtc/ulp.inl | 321 - include/glm/gtc/vec1.hpp | 164 - include/glm/gtc/vec1.inl | 2 - include/glm/gtx/associated_min_max.hpp | 202 - include/glm/gtx/associated_min_max.inl | 355 - include/glm/gtx/bit.hpp | 95 - include/glm/gtx/bit.inl | 93 - include/glm/gtx/closest_point.hpp | 45 - include/glm/gtx/closest_point.inl | 46 - include/glm/gtx/color_space.hpp | 68 - include/glm/gtx/color_space.inl | 141 - include/glm/gtx/color_space_YCoCg.hpp | 56 - include/glm/gtx/color_space_YCoCg.inl | 108 - include/glm/gtx/common.hpp | 53 - include/glm/gtx/common.inl | 112 - include/glm/gtx/compatibility.hpp | 130 - include/glm/gtx/compatibility.inl | 65 - include/glm/gtx/component_wise.hpp | 65 - include/glm/gtx/component_wise.inl | 128 - include/glm/gtx/dual_quaternion.hpp | 266 - include/glm/gtx/dual_quaternion.inl | 351 - include/glm/gtx/euler_angles.hpp | 143 - include/glm/gtx/euler_angles.inl | 312 - include/glm/gtx/extend.hpp | 38 - include/glm/gtx/extend.inl | 49 - include/glm/gtx/extended_min_max.hpp | 133 - include/glm/gtx/extended_min_max.inl | 140 - include/glm/gtx/fast_exponential.hpp | 91 - include/glm/gtx/fast_exponential.inl | 137 - include/glm/gtx/fast_square_root.hpp | 88 - include/glm/gtx/fast_square_root.inl | 81 - include/glm/gtx/fast_trigonometry.hpp | 75 - include/glm/gtx/fast_trigonometry.inl | 143 - include/glm/gtx/float_notmalize.inl | 14 - include/glm/gtx/gradient_paint.hpp | 48 - include/glm/gtx/gradient_paint.inl | 37 - include/glm/gtx/handed_coordinate_space.hpp | 46 - include/glm/gtx/handed_coordinate_space.inl | 27 - include/glm/gtx/hash.hpp | 134 - include/glm/gtx/hash.inl | 185 - include/glm/gtx/integer.hpp | 72 - include/glm/gtx/integer.inl | 182 - include/glm/gtx/intersect.hpp | 87 - include/glm/gtx/intersect.inl | 170 - include/glm/gtx/io.hpp | 197 - include/glm/gtx/io.inl | 441 - include/glm/gtx/log_base.hpp | 44 - include/glm/gtx/log_base.inl | 18 - include/glm/gtx/matrix_cross_product.hpp | 43 - include/glm/gtx/matrix_cross_product.inl | 38 - include/glm/gtx/matrix_decompose.hpp | 42 - include/glm/gtx/matrix_decompose.inl | 194 - include/glm/gtx/matrix_interpolation.hpp | 61 - include/glm/gtx/matrix_interpolation.inl | 134 - include/glm/gtx/matrix_major_storage.hpp | 115 - include/glm/gtx/matrix_major_storage.inl | 167 - include/glm/gtx/matrix_operation.hpp | 84 - include/glm/gtx/matrix_operation.inl | 118 - include/glm/gtx/matrix_query.hpp | 73 - include/glm/gtx/matrix_query.inl | 114 - include/glm/gtx/matrix_transform_2d.hpp | 78 - include/glm/gtx/matrix_transform_2d.inl | 69 - include/glm/gtx/mixed_product.hpp | 37 - include/glm/gtx/mixed_product.inl | 16 - include/glm/gtx/norm.hpp | 86 - include/glm/gtx/norm.inl | 106 - include/glm/gtx/normal.hpp | 39 - include/glm/gtx/normal.inl | 16 - include/glm/gtx/normalize_dot.hpp | 45 - include/glm/gtx/normalize_dot.inl | 17 - include/glm/gtx/number_precision.hpp | 57 - include/glm/gtx/number_precision.inl | 7 - include/glm/gtx/optimum_pow.hpp | 50 - include/glm/gtx/optimum_pow.inl | 23 - include/glm/gtx/orthonormalize.hpp | 45 - include/glm/gtx/orthonormalize.inl | 30 - include/glm/gtx/perpendicular.hpp | 39 - include/glm/gtx/perpendicular.inl | 15 - include/glm/gtx/polar_coordinates.hpp | 44 - include/glm/gtx/polar_coordinates.inl | 37 - include/glm/gtx/projection.hpp | 36 - include/glm/gtx/projection.inl | 11 - include/glm/gtx/quaternion.hpp | 185 - include/glm/gtx/quaternion.inl | 212 - include/glm/gtx/range.hpp | 85 - include/glm/gtx/raw_data.hpp | 47 - include/glm/gtx/raw_data.inl | 2 - include/glm/gtx/rotate_normalized_axis.hpp | 64 - include/glm/gtx/rotate_normalized_axis.inl | 59 - include/glm/gtx/rotate_vector.hpp | 117 - include/glm/gtx/rotate_vector.inl | 188 - include/glm/gtx/scalar_multiplication.hpp | 69 - include/glm/gtx/scalar_relational.hpp | 32 - include/glm/gtx/scalar_relational.inl | 89 - include/glm/gtx/spline.hpp | 61 - include/glm/gtx/spline.inl | 63 - include/glm/gtx/std_based_type.hpp | 63 - include/glm/gtx/std_based_type.inl | 7 - include/glm/gtx/string_cast.hpp | 47 - include/glm/gtx/string_cast.inl | 458 - include/glm/gtx/transform.hpp | 56 - include/glm/gtx/transform.inl | 24 - include/glm/gtx/transform2.hpp | 107 - include/glm/gtx/transform2.inl | 126 - include/glm/gtx/type_aligned.hpp | 966 -- include/glm/gtx/type_aligned.inl | 7 - include/glm/gtx/type_trait.hpp | 252 - include/glm/gtx/type_trait.inl | 0 include/glm/gtx/vector_angle.hpp | 60 - include/glm/gtx/vector_angle.inl | 58 - include/glm/gtx/vector_query.hpp | 62 - include/glm/gtx/vector_query.inl | 193 - include/glm/gtx/wrap.hpp | 51 - include/glm/gtx/wrap.inl | 58 - include/glm/integer.hpp | 6 - include/glm/mat2x2.hpp | 52 - include/glm/mat2x3.hpp | 32 - include/glm/mat2x4.hpp | 31 - include/glm/mat3x2.hpp | 31 - include/glm/mat3x3.hpp | 52 - include/glm/mat3x4.hpp | 31 - include/glm/mat4x2.hpp | 31 - include/glm/mat4x3.hpp | 31 - include/glm/mat4x4.hpp | 52 - include/glm/matrix.hpp | 6 - include/glm/packing.hpp | 6 - include/glm/simd/common.h | 240 - include/glm/simd/exponential.h | 20 - include/glm/simd/geometric.h | 124 - include/glm/simd/integer.h | 115 - include/glm/simd/matrix.h | 1028 -- include/glm/simd/packing.h | 8 - include/glm/simd/platform.h | 452 - include/glm/simd/trigonometric.h | 9 - include/glm/simd/vector_relational.h | 8 - include/glm/trigonometric.hpp | 6 - include/glm/vec2.hpp | 6 - include/glm/vec3.hpp | 6 - include/glm/vec4.hpp | 6 - include/glm/vector_relational.hpp | 6 - include/imconfig.h | 72 - include/imgui.h | 1894 --- include/imgui_internal.h | 1147 -- include/picojson.h | 1168 -- include/{ => sre/impl}/TextEditor.h | 0 include/stb_rect_pack.h | 623 - include/stb_textedit.h | 1321 -- include/stb_truetype.h | 4854 ------ src/CMakeLists.txt | 5 +- src/imgui/imgui.cpp | 13628 ---------------- src/imgui/imgui_draw.cpp | 2994 ---- src/sre/Camera.cpp | 1 + src/sre/Inspector.cpp | 3 +- src/sre/Mesh.cpp | 1 + src/sre/ModelImporter.cpp | 1 + src/sre/RenderPass.cpp | 1 + src/sre/Shader.cpp | 1 + src/sre/Sprite.cpp | 1 + src/sre/SpriteAtlas.cpp | 1 + src/sre/VR.cpp | 1 + src/{imgui => sre/impl}/TextEditor.cpp | 2 +- src/{imgui => sre/impl}/imgui_sre.cpp | 0 submodules/CMakeLists.txt | 12 + test/benchmark64k-heavy.cpp | 2 +- test/bumpmap.cpp | 1 + test/custom-mesh-layout-default-values.cpp | 1 + test/custom-mesh-layout-ints.cpp | 1 + test/deallocation.cpp | 1 + test/gamma.cpp | 1 + test/imgui-color-test.cpp | 2 +- test/imgui_demo.cpp | 1 + test/matrix-uniforms.cpp | 1 + test/multi-cameras.cpp | 2 +- test/multiple-lights.cpp | 1 + test/multiple-materials.cpp | 2 +- test/particle-sprite.cpp | 1 + test/particle-test.cpp | 1 + test/pbr-test.cpp | 1 + test/polygon-offset-example.cpp | 1 + test/primitives-test.cpp | 2 +- test/render-depth.cpp | 1 + test/screen-point-to-ray.cpp | 1 + test/shadow-test.cpp | 1 + test/spinning-sphere-cubemap.cpp | 1 + test/sprite-test.cpp | 2 +- test/static_vertex_attribute.cpp | 2 +- test/stencil_test.cpp | 1 + test/texture-test.cpp | 1 + 324 files changed, 78 insertions(+), 77662 deletions(-) create mode 100644 .gitmodules delete mode 100755 include/glm/CMakeLists.txt delete mode 100755 include/glm/common.hpp delete mode 100755 include/glm/detail/_features.hpp delete mode 100755 include/glm/detail/_fixes.hpp delete mode 100755 include/glm/detail/_noise.hpp delete mode 100755 include/glm/detail/_swizzle.hpp delete mode 100755 include/glm/detail/_swizzle_func.hpp delete mode 100755 include/glm/detail/_vectorize.hpp delete mode 100755 include/glm/detail/dummy.cpp delete mode 100755 include/glm/detail/func_common.hpp delete mode 100755 include/glm/detail/func_common.inl delete mode 100755 include/glm/detail/func_common_simd.inl delete mode 100755 include/glm/detail/func_exponential.hpp delete mode 100755 include/glm/detail/func_exponential.inl delete mode 100755 include/glm/detail/func_exponential_simd.inl delete mode 100755 include/glm/detail/func_geometric.hpp delete mode 100755 include/glm/detail/func_geometric.inl delete mode 100755 include/glm/detail/func_geometric_simd.inl delete mode 100755 include/glm/detail/func_integer.hpp delete mode 100755 include/glm/detail/func_integer.inl delete mode 100755 include/glm/detail/func_integer_simd.inl delete mode 100755 include/glm/detail/func_matrix.hpp delete mode 100755 include/glm/detail/func_matrix.inl delete mode 100755 include/glm/detail/func_matrix_simd.inl delete mode 100755 include/glm/detail/func_packing.hpp delete mode 100755 include/glm/detail/func_packing.inl delete mode 100755 include/glm/detail/func_packing_simd.inl delete mode 100755 include/glm/detail/func_trigonometric.hpp delete mode 100755 include/glm/detail/func_trigonometric.inl delete mode 100755 include/glm/detail/func_trigonometric_simd.inl delete mode 100755 include/glm/detail/func_vector_relational.hpp delete mode 100755 include/glm/detail/func_vector_relational.inl delete mode 100755 include/glm/detail/func_vector_relational_simd.inl delete mode 100755 include/glm/detail/glm.cpp delete mode 100755 include/glm/detail/precision.hpp delete mode 100755 include/glm/detail/setup.hpp delete mode 100755 include/glm/detail/type_float.hpp delete mode 100755 include/glm/detail/type_gentype.hpp delete mode 100755 include/glm/detail/type_gentype.inl delete mode 100755 include/glm/detail/type_half.hpp delete mode 100755 include/glm/detail/type_half.inl delete mode 100755 include/glm/detail/type_int.hpp delete mode 100755 include/glm/detail/type_mat.hpp delete mode 100755 include/glm/detail/type_mat.inl delete mode 100755 include/glm/detail/type_mat2x2.hpp delete mode 100755 include/glm/detail/type_mat2x2.inl delete mode 100755 include/glm/detail/type_mat2x3.hpp delete mode 100755 include/glm/detail/type_mat2x3.inl delete mode 100755 include/glm/detail/type_mat2x4.hpp delete mode 100755 include/glm/detail/type_mat2x4.inl delete mode 100755 include/glm/detail/type_mat3x2.hpp delete mode 100755 include/glm/detail/type_mat3x2.inl delete mode 100755 include/glm/detail/type_mat3x3.hpp delete mode 100755 include/glm/detail/type_mat3x3.inl delete mode 100755 include/glm/detail/type_mat3x4.hpp delete mode 100755 include/glm/detail/type_mat3x4.inl delete mode 100755 include/glm/detail/type_mat4x2.hpp delete mode 100755 include/glm/detail/type_mat4x2.inl delete mode 100755 include/glm/detail/type_mat4x3.hpp delete mode 100755 include/glm/detail/type_mat4x3.inl delete mode 100755 include/glm/detail/type_mat4x4.hpp delete mode 100755 include/glm/detail/type_mat4x4.inl delete mode 100755 include/glm/detail/type_mat4x4_simd.inl delete mode 100755 include/glm/detail/type_vec.hpp delete mode 100755 include/glm/detail/type_vec.inl delete mode 100755 include/glm/detail/type_vec1.hpp delete mode 100755 include/glm/detail/type_vec1.inl delete mode 100755 include/glm/detail/type_vec2.hpp delete mode 100755 include/glm/detail/type_vec2.inl delete mode 100755 include/glm/detail/type_vec3.hpp delete mode 100755 include/glm/detail/type_vec3.inl delete mode 100755 include/glm/detail/type_vec4.hpp delete mode 100755 include/glm/detail/type_vec4.inl delete mode 100755 include/glm/detail/type_vec4_simd.inl delete mode 100755 include/glm/exponential.hpp delete mode 100755 include/glm/ext.hpp delete mode 100755 include/glm/fwd.hpp delete mode 100755 include/glm/geometric.hpp delete mode 100755 include/glm/glm.hpp delete mode 100755 include/glm/gtc/bitfield.hpp delete mode 100755 include/glm/gtc/bitfield.inl delete mode 100755 include/glm/gtc/color_encoding.inl delete mode 100755 include/glm/gtc/color_space.hpp delete mode 100755 include/glm/gtc/color_space.inl delete mode 100755 include/glm/gtc/constants.hpp delete mode 100755 include/glm/gtc/constants.inl delete mode 100755 include/glm/gtc/epsilon.hpp delete mode 100755 include/glm/gtc/epsilon.inl delete mode 100755 include/glm/gtc/functions.hpp delete mode 100755 include/glm/gtc/functions.inl delete mode 100755 include/glm/gtc/integer.hpp delete mode 100755 include/glm/gtc/integer.inl delete mode 100755 include/glm/gtc/matrix_access.hpp delete mode 100755 include/glm/gtc/matrix_access.inl delete mode 100755 include/glm/gtc/matrix_integer.hpp delete mode 100755 include/glm/gtc/matrix_inverse.hpp delete mode 100755 include/glm/gtc/matrix_inverse.inl delete mode 100755 include/glm/gtc/matrix_transform.hpp delete mode 100755 include/glm/gtc/matrix_transform.inl delete mode 100755 include/glm/gtc/noise.hpp delete mode 100755 include/glm/gtc/noise.inl delete mode 100755 include/glm/gtc/packing.hpp delete mode 100755 include/glm/gtc/packing.inl delete mode 100755 include/glm/gtc/quaternion.hpp delete mode 100755 include/glm/gtc/quaternion.inl delete mode 100755 include/glm/gtc/quaternion_simd.inl delete mode 100755 include/glm/gtc/random.hpp delete mode 100755 include/glm/gtc/random.inl delete mode 100755 include/glm/gtc/reciprocal.hpp delete mode 100755 include/glm/gtc/reciprocal.inl delete mode 100755 include/glm/gtc/round.hpp delete mode 100755 include/glm/gtc/round.inl delete mode 100755 include/glm/gtc/type_aligned.hpp delete mode 100755 include/glm/gtc/type_precision.hpp delete mode 100755 include/glm/gtc/type_precision.inl delete mode 100755 include/glm/gtc/type_ptr.hpp delete mode 100755 include/glm/gtc/type_ptr.inl delete mode 100755 include/glm/gtc/ulp.hpp delete mode 100755 include/glm/gtc/ulp.inl delete mode 100755 include/glm/gtc/vec1.hpp delete mode 100755 include/glm/gtc/vec1.inl delete mode 100755 include/glm/gtx/associated_min_max.hpp delete mode 100755 include/glm/gtx/associated_min_max.inl delete mode 100755 include/glm/gtx/bit.hpp delete mode 100755 include/glm/gtx/bit.inl delete mode 100755 include/glm/gtx/closest_point.hpp delete mode 100755 include/glm/gtx/closest_point.inl delete mode 100755 include/glm/gtx/color_space.hpp delete mode 100755 include/glm/gtx/color_space.inl delete mode 100755 include/glm/gtx/color_space_YCoCg.hpp delete mode 100755 include/glm/gtx/color_space_YCoCg.inl delete mode 100755 include/glm/gtx/common.hpp delete mode 100755 include/glm/gtx/common.inl delete mode 100755 include/glm/gtx/compatibility.hpp delete mode 100755 include/glm/gtx/compatibility.inl delete mode 100755 include/glm/gtx/component_wise.hpp delete mode 100755 include/glm/gtx/component_wise.inl delete mode 100755 include/glm/gtx/dual_quaternion.hpp delete mode 100755 include/glm/gtx/dual_quaternion.inl delete mode 100755 include/glm/gtx/euler_angles.hpp delete mode 100755 include/glm/gtx/euler_angles.inl delete mode 100755 include/glm/gtx/extend.hpp delete mode 100755 include/glm/gtx/extend.inl delete mode 100755 include/glm/gtx/extended_min_max.hpp delete mode 100755 include/glm/gtx/extended_min_max.inl delete mode 100755 include/glm/gtx/fast_exponential.hpp delete mode 100755 include/glm/gtx/fast_exponential.inl delete mode 100755 include/glm/gtx/fast_square_root.hpp delete mode 100755 include/glm/gtx/fast_square_root.inl delete mode 100755 include/glm/gtx/fast_trigonometry.hpp delete mode 100755 include/glm/gtx/fast_trigonometry.inl delete mode 100755 include/glm/gtx/float_notmalize.inl delete mode 100755 include/glm/gtx/gradient_paint.hpp delete mode 100755 include/glm/gtx/gradient_paint.inl delete mode 100755 include/glm/gtx/handed_coordinate_space.hpp delete mode 100755 include/glm/gtx/handed_coordinate_space.inl delete mode 100755 include/glm/gtx/hash.hpp delete mode 100755 include/glm/gtx/hash.inl delete mode 100755 include/glm/gtx/integer.hpp delete mode 100755 include/glm/gtx/integer.inl delete mode 100755 include/glm/gtx/intersect.hpp delete mode 100755 include/glm/gtx/intersect.inl delete mode 100755 include/glm/gtx/io.hpp delete mode 100755 include/glm/gtx/io.inl delete mode 100755 include/glm/gtx/log_base.hpp delete mode 100755 include/glm/gtx/log_base.inl delete mode 100755 include/glm/gtx/matrix_cross_product.hpp delete mode 100755 include/glm/gtx/matrix_cross_product.inl delete mode 100755 include/glm/gtx/matrix_decompose.hpp delete mode 100755 include/glm/gtx/matrix_decompose.inl delete mode 100755 include/glm/gtx/matrix_interpolation.hpp delete mode 100755 include/glm/gtx/matrix_interpolation.inl delete mode 100755 include/glm/gtx/matrix_major_storage.hpp delete mode 100755 include/glm/gtx/matrix_major_storage.inl delete mode 100755 include/glm/gtx/matrix_operation.hpp delete mode 100755 include/glm/gtx/matrix_operation.inl delete mode 100755 include/glm/gtx/matrix_query.hpp delete mode 100755 include/glm/gtx/matrix_query.inl delete mode 100755 include/glm/gtx/matrix_transform_2d.hpp delete mode 100755 include/glm/gtx/matrix_transform_2d.inl delete mode 100755 include/glm/gtx/mixed_product.hpp delete mode 100755 include/glm/gtx/mixed_product.inl delete mode 100755 include/glm/gtx/norm.hpp delete mode 100755 include/glm/gtx/norm.inl delete mode 100755 include/glm/gtx/normal.hpp delete mode 100755 include/glm/gtx/normal.inl delete mode 100755 include/glm/gtx/normalize_dot.hpp delete mode 100755 include/glm/gtx/normalize_dot.inl delete mode 100755 include/glm/gtx/number_precision.hpp delete mode 100755 include/glm/gtx/number_precision.inl delete mode 100755 include/glm/gtx/optimum_pow.hpp delete mode 100755 include/glm/gtx/optimum_pow.inl delete mode 100755 include/glm/gtx/orthonormalize.hpp delete mode 100755 include/glm/gtx/orthonormalize.inl delete mode 100755 include/glm/gtx/perpendicular.hpp delete mode 100755 include/glm/gtx/perpendicular.inl delete mode 100755 include/glm/gtx/polar_coordinates.hpp delete mode 100755 include/glm/gtx/polar_coordinates.inl delete mode 100755 include/glm/gtx/projection.hpp delete mode 100755 include/glm/gtx/projection.inl delete mode 100755 include/glm/gtx/quaternion.hpp delete mode 100755 include/glm/gtx/quaternion.inl delete mode 100755 include/glm/gtx/range.hpp delete mode 100755 include/glm/gtx/raw_data.hpp delete mode 100755 include/glm/gtx/raw_data.inl delete mode 100755 include/glm/gtx/rotate_normalized_axis.hpp delete mode 100755 include/glm/gtx/rotate_normalized_axis.inl delete mode 100755 include/glm/gtx/rotate_vector.hpp delete mode 100755 include/glm/gtx/rotate_vector.inl delete mode 100755 include/glm/gtx/scalar_multiplication.hpp delete mode 100755 include/glm/gtx/scalar_relational.hpp delete mode 100755 include/glm/gtx/scalar_relational.inl delete mode 100755 include/glm/gtx/spline.hpp delete mode 100755 include/glm/gtx/spline.inl delete mode 100755 include/glm/gtx/std_based_type.hpp delete mode 100755 include/glm/gtx/std_based_type.inl delete mode 100755 include/glm/gtx/string_cast.hpp delete mode 100755 include/glm/gtx/string_cast.inl delete mode 100755 include/glm/gtx/transform.hpp delete mode 100755 include/glm/gtx/transform.inl delete mode 100755 include/glm/gtx/transform2.hpp delete mode 100755 include/glm/gtx/transform2.inl delete mode 100755 include/glm/gtx/type_aligned.hpp delete mode 100755 include/glm/gtx/type_aligned.inl delete mode 100755 include/glm/gtx/type_trait.hpp delete mode 100755 include/glm/gtx/type_trait.inl delete mode 100755 include/glm/gtx/vector_angle.hpp delete mode 100755 include/glm/gtx/vector_angle.inl delete mode 100755 include/glm/gtx/vector_query.hpp delete mode 100755 include/glm/gtx/vector_query.inl delete mode 100755 include/glm/gtx/wrap.hpp delete mode 100755 include/glm/gtx/wrap.inl delete mode 100755 include/glm/integer.hpp delete mode 100755 include/glm/mat2x2.hpp delete mode 100755 include/glm/mat2x3.hpp delete mode 100755 include/glm/mat2x4.hpp delete mode 100755 include/glm/mat3x2.hpp delete mode 100755 include/glm/mat3x3.hpp delete mode 100755 include/glm/mat3x4.hpp delete mode 100755 include/glm/mat4x2.hpp delete mode 100755 include/glm/mat4x3.hpp delete mode 100755 include/glm/mat4x4.hpp delete mode 100755 include/glm/matrix.hpp delete mode 100755 include/glm/packing.hpp delete mode 100755 include/glm/simd/common.h delete mode 100755 include/glm/simd/exponential.h delete mode 100755 include/glm/simd/geometric.h delete mode 100755 include/glm/simd/integer.h delete mode 100755 include/glm/simd/matrix.h delete mode 100755 include/glm/simd/packing.h delete mode 100755 include/glm/simd/platform.h delete mode 100755 include/glm/simd/trigonometric.h delete mode 100755 include/glm/simd/vector_relational.h delete mode 100755 include/glm/trigonometric.hpp delete mode 100755 include/glm/vec2.hpp delete mode 100755 include/glm/vec3.hpp delete mode 100755 include/glm/vec4.hpp delete mode 100755 include/glm/vector_relational.hpp delete mode 100755 include/imconfig.h delete mode 100755 include/imgui.h delete mode 100755 include/imgui_internal.h delete mode 100644 include/picojson.h rename include/{ => sre/impl}/TextEditor.h (100%) delete mode 100755 include/stb_rect_pack.h delete mode 100755 include/stb_textedit.h delete mode 100755 include/stb_truetype.h delete mode 100755 src/imgui/imgui.cpp delete mode 100755 src/imgui/imgui_draw.cpp rename src/{imgui => sre/impl}/TextEditor.cpp (99%) rename src/{imgui => sre/impl}/imgui_sre.cpp (100%) create mode 100644 submodules/CMakeLists.txt diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..e30b4c52 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,9 @@ +[submodule "submodules/imgui"] + path = submodules/imgui + url = https://github.com/ocornut/imgui.git +[submodule "submodules/glm"] + path = submodules/glm + url = https://github.com/g-truc/glm.git +[submodule "submodules/picojson"] + path = submodules/picojson + url = https://github.com/kazuho/picojson.git diff --git a/CMakeLists.txt b/CMakeLists.txt index eec88422..afad45b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,6 +68,9 @@ IF (USE_OPENVR) ENDIF(APPLE) ENDIF(USE_OPENVR) +add_subdirectory(submodules) +include_directories(${EXTRA_INCLUDE}) +message(${EXTRA_INCLUDE}) add_subdirectory(src) add_subdirectory(examples) diff --git a/examples/02_spheres.cpp b/examples/02_spheres.cpp index c8528f45..1d3600fb 100644 --- a/examples/02_spheres.cpp +++ b/examples/02_spheres.cpp @@ -4,6 +4,7 @@ #include "sre/Renderer.hpp" #include "sre/Material.hpp" +#define GLM_ENABLE_EXPERIMENTAL #include #include #include diff --git a/examples/03_spinning-cube.cpp b/examples/03_spinning-cube.cpp index 8e3fc90a..5c00423a 100644 --- a/examples/03_spinning-cube.cpp +++ b/examples/03_spinning-cube.cpp @@ -7,7 +7,7 @@ #include "sre/Material.hpp" #include "sre/SDLRenderer.hpp" - +#define GLM_ENABLE_EXPERIMENTAL #include #include #include diff --git a/examples/04_spinning-primitives-tex.cpp b/examples/04_spinning-primitives-tex.cpp index 5d3f9c68..0e9e69d2 100644 --- a/examples/04_spinning-primitives-tex.cpp +++ b/examples/04_spinning-primitives-tex.cpp @@ -6,6 +6,7 @@ #include "sre/Renderer.hpp" #include "sre/Material.hpp" +#define GLM_ENABLE_EXPERIMENTAL #include #include #include diff --git a/examples/05_obj-viewer.cpp b/examples/05_obj-viewer.cpp index 764996aa..931ed358 100644 --- a/examples/05_obj-viewer.cpp +++ b/examples/05_obj-viewer.cpp @@ -7,6 +7,7 @@ #include "sre/Material.hpp" #include "sre/SDLRenderer.hpp" +#define GLM_ENABLE_EXPERIMENTAL #include #include #include diff --git a/examples/06_custom-mesh-layout.cpp b/examples/06_custom-mesh-layout.cpp index 4e3c679f..3effc9ca 100644 --- a/examples/06_custom-mesh-layout.cpp +++ b/examples/06_custom-mesh-layout.cpp @@ -4,6 +4,7 @@ #include "sre/Renderer.hpp" #include "sre/Material.hpp" +#define GLM_ENABLE_EXPERIMENTAL #include #include #include diff --git a/examples/07_matcap.cpp b/examples/07_matcap.cpp index 48070fd6..0188ebd2 100644 --- a/examples/07_matcap.cpp +++ b/examples/07_matcap.cpp @@ -4,6 +4,7 @@ #include "sre/Renderer.hpp" #include "sre/Material.hpp" +#define GLM_ENABLE_EXPERIMENTAL #include #include #include diff --git a/examples/08_gui.cpp b/examples/08_gui.cpp index f1f67b93..e23ed03d 100644 --- a/examples/08_gui.cpp +++ b/examples/08_gui.cpp @@ -7,6 +7,7 @@ #include "sre/Inspector.hpp" #include "sre/Material.hpp" +#define GLM_ENABLE_EXPERIMENTAL #include #include diff --git a/examples/09_picking.cpp b/examples/09_picking.cpp index f3e0430c..e6e08d95 100644 --- a/examples/09_picking.cpp +++ b/examples/09_picking.cpp @@ -6,6 +6,7 @@ #include "sre/Renderer.hpp" #include "sre/Material.hpp" +#define GLM_ENABLE_EXPERIMENTAL #include #include #include diff --git a/examples/10_skybox-example.cpp b/examples/10_skybox-example.cpp index 6f1a92c2..b6f641b1 100644 --- a/examples/10_skybox-example.cpp +++ b/examples/10_skybox-example.cpp @@ -7,7 +7,7 @@ #include "sre/Material.hpp" #include "sre/SDLRenderer.hpp" - +#define GLM_ENABLE_EXPERIMENTAL #include #include #include diff --git a/examples/11_sprite-example.cpp b/examples/11_sprite-example.cpp index 2fc49e3a..d82be21c 100644 --- a/examples/11_sprite-example.cpp +++ b/examples/11_sprite-example.cpp @@ -11,7 +11,7 @@ #include "sre/Material.hpp" #include "sre/SDLRenderer.hpp" - +#define GLM_ENABLE_EXPERIMENTAL #include #include diff --git a/examples/12_render-to-texture.cpp b/examples/12_render-to-texture.cpp index 0a31f530..8fbc9db2 100644 --- a/examples/12_render-to-texture.cpp +++ b/examples/12_render-to-texture.cpp @@ -7,6 +7,7 @@ #include "sre/Material.hpp" #include "sre/SDLRenderer.hpp" +#define GLM_ENABLE_EXPERIMENTAL #include #include #include diff --git a/examples/13_benchmark64k.cpp b/examples/13_benchmark64k.cpp index 90be708e..e19e5c7f 100644 --- a/examples/13_benchmark64k.cpp +++ b/examples/13_benchmark64k.cpp @@ -7,6 +7,7 @@ #include "sre/Material.hpp" #include "sre/SDLRenderer.hpp" +#define GLM_ENABLE_EXPERIMENTAL #include #include #include diff --git a/examples/14_spinning-primitives-openvr.cpp b/examples/14_spinning-primitives-openvr.cpp index 5bf3175b..bd00bbb4 100644 --- a/examples/14_spinning-primitives-openvr.cpp +++ b/examples/14_spinning-primitives-openvr.cpp @@ -7,6 +7,7 @@ #include "sre/VR.hpp" #include "sre/Material.hpp" +#define GLM_ENABLE_EXPERIMENTAL #include #include #include diff --git a/examples/15_cloth_simulation.cpp b/examples/15_cloth_simulation.cpp index d0cbe7e4..d1b6aa2f 100644 --- a/examples/15_cloth_simulation.cpp +++ b/examples/15_cloth_simulation.cpp @@ -7,7 +7,7 @@ #include "sre/Material.hpp" #include "sre/SDLRenderer.hpp" - +#define GLM_ENABLE_EXPERIMENTAL #include #include #include diff --git a/examples/16_shadows.cpp b/examples/16_shadows.cpp index 39299a80..5f673f2a 100644 --- a/examples/16_shadows.cpp +++ b/examples/16_shadows.cpp @@ -4,6 +4,7 @@ #include "sre/Renderer.hpp" #include "sre/Material.hpp" +#define GLM_ENABLE_EXPERIMENTAL #include #include #include diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index acd57cef..ee6fdaa2 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,4 +1,4 @@ -SET(scr_files 00_hello-engine 01_hello-engine-raw 02_spheres 03_spinning-cube 04_spinning-primitives-tex 05_obj-viewer 06_custom-mesh-layout 07_matcap 08_gui 09_picking 10_skybox-example 11_sprite-example 12_render-to-texture 13_benchmark64k 14_spinning-primitives-openvr 15_cloth_simulation 16_shadows) +SET(scr_files 00_hello-engine 01_hello-engine-raw 02_spheres 03_spinning-cube 04_spinning-primitives-tex 05_obj-viewer 06_custom-mesh-layout 07_matcap 08_gui 09_picking 10_skybox-example 11_sprite-example 12_render-to-texture 13_benchmark64k 14_spinning-primitives-openvr 15_cloth_simulation 16_shadows 17_deferred-shading) # Create custom build targets FOREACH(scr_file ${scr_files}) diff --git a/include/glm/CMakeLists.txt b/include/glm/CMakeLists.txt deleted file mode 100755 index d60a8877..00000000 --- a/include/glm/CMakeLists.txt +++ /dev/null @@ -1,67 +0,0 @@ -file(GLOB ROOT_SOURCE *.cpp) -file(GLOB ROOT_INLINE *.inl) -file(GLOB ROOT_HEADER *.hpp) -file(GLOB ROOT_TEXT ../*.txt) -file(GLOB ROOT_MD ../*.md) -file(GLOB ROOT_NAT ../util/glm.natvis) - -file(GLOB_RECURSE CORE_SOURCE ./detail/*.cpp) -file(GLOB_RECURSE CORE_INLINE ./detail/*.inl) -file(GLOB_RECURSE CORE_HEADER ./detail/*.hpp) - -file(GLOB_RECURSE GTC_SOURCE ./gtc/*.cpp) -file(GLOB_RECURSE GTC_INLINE ./gtc/*.inl) -file(GLOB_RECURSE GTC_HEADER ./gtc/*.hpp) - -file(GLOB_RECURSE GTX_SOURCE ./gtx/*.cpp) -file(GLOB_RECURSE GTX_INLINE ./gtx/*.inl) -file(GLOB_RECURSE GTX_HEADER ./gtx/*.hpp) - -file(GLOB_RECURSE SIMD_SOURCE ./simd/*.cpp) -file(GLOB_RECURSE SIMD_INLINE ./simd/*.inl) -file(GLOB_RECURSE SIMD_HEADER ./simd/*.h) - -source_group("Text Files" FILES ${ROOT_TEXT} ${ROOT_MD}) -source_group("Core Files" FILES ${CORE_SOURCE}) -source_group("Core Files" FILES ${CORE_INLINE}) -source_group("Core Files" FILES ${CORE_HEADER}) -source_group("GTC Files" FILES ${GTC_SOURCE}) -source_group("GTC Files" FILES ${GTC_INLINE}) -source_group("GTC Files" FILES ${GTC_HEADER}) -source_group("GTX Files" FILES ${GTX_SOURCE}) -source_group("GTX Files" FILES ${GTX_INLINE}) -source_group("GTX Files" FILES ${GTX_HEADER}) -source_group("SIMD Files" FILES ${SIMD_SOURCE}) -source_group("SIMD Files" FILES ${SIMD_INLINE}) -source_group("SIMD Files" FILES ${SIMD_HEADER}) - -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..) - -if(GLM_STATIC_LIBRARY_ENABLE OR GLM_DYNAMIC_LIBRARY_ENABLE) - if(GLM_STATIC_LIBRARY_ENABLE) - add_library(glm_static STATIC ${ROOT_TEXT} ${ROOT_MD} ${ROOT_NAT} - ${ROOT_SOURCE} ${ROOT_INLINE} ${ROOT_HEADER} - ${CORE_SOURCE} ${CORE_INLINE} ${CORE_HEADER} - ${GTC_SOURCE} ${GTC_INLINE} ${GTC_HEADER} - ${GTX_SOURCE} ${GTX_INLINE} ${GTX_HEADER} - ${SIMD_SOURCE} ${SIMD_INLINE} ${SIMD_HEADER}) - endif(GLM_STATIC_LIBRARY_ENABLE) - - if(GLM_DYNAMIC_LIBRARY_ENABLE) - add_library(glm_shared SHARED ${ROOT_TEXT} ${ROOT_MD} ${ROOT_NAT} - ${ROOT_SOURCE} ${ROOT_INLINE} ${ROOT_HEADER} - ${CORE_SOURCE} ${CORE_INLINE} ${CORE_HEADER} - ${GTC_SOURCE} ${GTC_INLINE} ${GTC_HEADER} - ${GTX_SOURCE} ${GTX_INLINE} ${GTX_HEADER} - ${SIMD_SOURCE} ${SIMD_INLINE} ${SIMD_HEADER}) - endif(GLM_DYNAMIC_LIBRARY_ENABLE) - -else(GLM_STATIC_LIBRARY_ENABLE OR GLM_DYNAMIC_LIBRARY_ENABLE) - add_executable(glm_dummy ${ROOT_TEXT} ${ROOT_MD} ${ROOT_NAT} - ${ROOT_SOURCE} ${ROOT_INLINE} ${ROOT_HEADER} - ${CORE_SOURCE} ${CORE_INLINE} ${CORE_HEADER} - ${GTC_SOURCE} ${GTC_INLINE} ${GTC_HEADER} - ${GTX_SOURCE} ${GTX_INLINE} ${GTX_HEADER} - ${SIMD_SOURCE} ${SIMD_INLINE} ${SIMD_HEADER}) - -endif(GLM_STATIC_LIBRARY_ENABLE OR GLM_DYNAMIC_LIBRARY_ENABLE) diff --git a/include/glm/common.hpp b/include/glm/common.hpp deleted file mode 100755 index f57e800e..00000000 --- a/include/glm/common.hpp +++ /dev/null @@ -1,6 +0,0 @@ -/// @ref core -/// @file glm/common.hpp - -#pragma once - -#include "detail/func_common.hpp" diff --git a/include/glm/detail/_features.hpp b/include/glm/detail/_features.hpp deleted file mode 100755 index 97dd6330..00000000 --- a/include/glm/detail/_features.hpp +++ /dev/null @@ -1,399 +0,0 @@ -/// @ref core -/// @file glm/detail/_features.hpp - -#pragma once - -// #define GLM_CXX98_EXCEPTIONS -// #define GLM_CXX98_RTTI - -// #define GLM_CXX11_RVALUE_REFERENCES -// Rvalue references - GCC 4.3 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2118.html - -// GLM_CXX11_TRAILING_RETURN -// Rvalue references for *this - GCC not supported -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2439.htm - -// GLM_CXX11_NONSTATIC_MEMBER_INIT -// Initialization of class objects by rvalues - GCC any -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1610.html - -// GLM_CXX11_NONSTATIC_MEMBER_INIT -// Non-static data member initializers - GCC 4.7 -// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2756.htm - -// #define GLM_CXX11_VARIADIC_TEMPLATE -// Variadic templates - GCC 4.3 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2242.pdf - -// -// Extending variadic template template parameters - GCC 4.4 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2555.pdf - -// #define GLM_CXX11_GENERALIZED_INITIALIZERS -// Initializer lists - GCC 4.4 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2672.htm - -// #define GLM_CXX11_STATIC_ASSERT -// Static assertions - GCC 4.3 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1720.html - -// #define GLM_CXX11_AUTO_TYPE -// auto-typed variables - GCC 4.4 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1984.pdf - -// #define GLM_CXX11_AUTO_TYPE -// Multi-declarator auto - GCC 4.4 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1737.pdf - -// #define GLM_CXX11_AUTO_TYPE -// Removal of auto as a storage-class specifier - GCC 4.4 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2546.htm - -// #define GLM_CXX11_AUTO_TYPE -// New function declarator syntax - GCC 4.4 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2541.htm - -// #define GLM_CXX11_LAMBDAS -// New wording for C++0x lambdas - GCC 4.5 -// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2927.pdf - -// #define GLM_CXX11_DECLTYPE -// Declared type of an expression - GCC 4.3 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2343.pdf - -// -// Right angle brackets - GCC 4.3 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1757.html - -// -// Default template arguments for function templates DR226 GCC 4.3 -// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#226 - -// -// Solving the SFINAE problem for expressions DR339 GCC 4.4 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2634.html - -// #define GLM_CXX11_ALIAS_TEMPLATE -// Template aliases N2258 GCC 4.7 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf - -// -// Extern templates N1987 Yes -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1987.htm - -// #define GLM_CXX11_NULLPTR -// Null pointer constant N2431 GCC 4.6 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf - -// #define GLM_CXX11_STRONG_ENUMS -// Strongly-typed enums N2347 GCC 4.4 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf - -// -// Forward declarations for enums N2764 GCC 4.6 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2764.pdf - -// -// Generalized attributes N2761 GCC 4.8 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2761.pdf - -// -// Generalized constant expressions N2235 GCC 4.6 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf - -// -// Alignment support N2341 GCC 4.8 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf - -// #define GLM_CXX11_DELEGATING_CONSTRUCTORS -// Delegating constructors N1986 GCC 4.7 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1986.pdf - -// -// Inheriting constructors N2540 GCC 4.8 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2540.htm - -// #define GLM_CXX11_EXPLICIT_CONVERSIONS -// Explicit conversion operators N2437 GCC 4.5 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2437.pdf - -// -// New character types N2249 GCC 4.4 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2249.html - -// -// Unicode string literals N2442 GCC 4.5 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm - -// -// Raw string literals N2442 GCC 4.5 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2442.htm - -// -// Universal character name literals N2170 GCC 4.5 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2170.html - -// #define GLM_CXX11_USER_LITERALS -// User-defined literals N2765 GCC 4.7 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2765.pdf - -// -// Standard Layout Types N2342 GCC 4.5 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm - -// #define GLM_CXX11_DEFAULTED_FUNCTIONS -// #define GLM_CXX11_DELETED_FUNCTIONS -// Defaulted and deleted functions N2346 GCC 4.4 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm - -// -// Extended friend declarations N1791 GCC 4.7 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1791.pdf - -// -// Extending sizeof N2253 GCC 4.4 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2253.html - -// #define GLM_CXX11_INLINE_NAMESPACES -// Inline namespaces N2535 GCC 4.4 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2535.htm - -// #define GLM_CXX11_UNRESTRICTED_UNIONS -// Unrestricted unions N2544 GCC 4.6 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf - -// #define GLM_CXX11_LOCAL_TYPE_TEMPLATE_ARGS -// Local and unnamed types as template arguments N2657 GCC 4.5 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm - -// #define GLM_CXX11_RANGE_FOR -// Range-based for N2930 GCC 4.6 -// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2930.html - -// #define GLM_CXX11_OVERRIDE_CONTROL -// Explicit virtual overrides N2928 N3206 N3272 GCC 4.7 -// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2009/n2928.htm -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3206.htm -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3272.htm - -// -// Minimal support for garbage collection and reachability-based leak detection N2670 No -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2670.htm - -// #define GLM_CXX11_NOEXCEPT -// Allowing move constructors to throw [noexcept] N3050 GCC 4.6 (core language only) -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3050.html - -// -// Defining move special member functions N3053 GCC 4.6 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3053.html - -// -// Sequence points N2239 Yes -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2239.html - -// -// Atomic operations N2427 GCC 4.4 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2239.html - -// -// Strong Compare and Exchange N2748 GCC 4.5 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html - -// -// Bidirectional Fences N2752 GCC 4.8 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2752.htm - -// -// Memory model N2429 GCC 4.8 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2429.htm - -// -// Data-dependency ordering: atomics and memory model N2664 GCC 4.4 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2664.htm - -// -// Propagating exceptions N2179 GCC 4.4 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2179.html - -// -// Abandoning a process and at_quick_exit N2440 GCC 4.8 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2440.htm - -// -// Allow atomics use in signal handlers N2547 Yes -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2547.htm - -// -// Thread-local storage N2659 GCC 4.8 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2659.htm - -// -// Dynamic initialization and destruction with concurrency N2660 GCC 4.3 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2660.htm - -// -// __func__ predefined identifier N2340 GCC 4.3 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2340.htm - -// -// C99 preprocessor N1653 GCC 4.3 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1653.htm - -// -// long long N1811 GCC 4.3 -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1811.pdf - -// -// Extended integral types N1988 Yes -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1988.pdf - -#if(GLM_COMPILER & GLM_COMPILER_GCC) - -# if(GLM_COMPILER >= GLM_COMPILER_GCC43) -# define GLM_CXX11_STATIC_ASSERT -# endif - -#elif(GLM_COMPILER & GLM_COMPILER_CLANG) -# if(__has_feature(cxx_exceptions)) -# define GLM_CXX98_EXCEPTIONS -# endif - -# if(__has_feature(cxx_rtti)) -# define GLM_CXX98_RTTI -# endif - -# if(__has_feature(cxx_access_control_sfinae)) -# define GLM_CXX11_ACCESS_CONTROL_SFINAE -# endif - -# if(__has_feature(cxx_alias_templates)) -# define GLM_CXX11_ALIAS_TEMPLATE -# endif - -# if(__has_feature(cxx_alignas)) -# define GLM_CXX11_ALIGNAS -# endif - -# if(__has_feature(cxx_attributes)) -# define GLM_CXX11_ATTRIBUTES -# endif - -# if(__has_feature(cxx_constexpr)) -# define GLM_CXX11_CONSTEXPR -# endif - -# if(__has_feature(cxx_decltype)) -# define GLM_CXX11_DECLTYPE -# endif - -# if(__has_feature(cxx_default_function_template_args)) -# define GLM_CXX11_DEFAULT_FUNCTION_TEMPLATE_ARGS -# endif - -# if(__has_feature(cxx_defaulted_functions)) -# define GLM_CXX11_DEFAULTED_FUNCTIONS -# endif - -# if(__has_feature(cxx_delegating_constructors)) -# define GLM_CXX11_DELEGATING_CONSTRUCTORS -# endif - -# if(__has_feature(cxx_deleted_functions)) -# define GLM_CXX11_DELETED_FUNCTIONS -# endif - -# if(__has_feature(cxx_explicit_conversions)) -# define GLM_CXX11_EXPLICIT_CONVERSIONS -# endif - -# if(__has_feature(cxx_generalized_initializers)) -# define GLM_CXX11_GENERALIZED_INITIALIZERS -# endif - -# if(__has_feature(cxx_implicit_moves)) -# define GLM_CXX11_IMPLICIT_MOVES -# endif - -# if(__has_feature(cxx_inheriting_constructors)) -# define GLM_CXX11_INHERITING_CONSTRUCTORS -# endif - -# if(__has_feature(cxx_inline_namespaces)) -# define GLM_CXX11_INLINE_NAMESPACES -# endif - -# if(__has_feature(cxx_lambdas)) -# define GLM_CXX11_LAMBDAS -# endif - -# if(__has_feature(cxx_local_type_template_args)) -# define GLM_CXX11_LOCAL_TYPE_TEMPLATE_ARGS -# endif - -# if(__has_feature(cxx_noexcept)) -# define GLM_CXX11_NOEXCEPT -# endif - -# if(__has_feature(cxx_nonstatic_member_init)) -# define GLM_CXX11_NONSTATIC_MEMBER_INIT -# endif - -# if(__has_feature(cxx_nullptr)) -# define GLM_CXX11_NULLPTR -# endif - -# if(__has_feature(cxx_override_control)) -# define GLM_CXX11_OVERRIDE_CONTROL -# endif - -# if(__has_feature(cxx_reference_qualified_functions)) -# define GLM_CXX11_REFERENCE_QUALIFIED_FUNCTIONS -# endif - -# if(__has_feature(cxx_range_for)) -# define GLM_CXX11_RANGE_FOR -# endif - -# if(__has_feature(cxx_raw_string_literals)) -# define GLM_CXX11_RAW_STRING_LITERALS -# endif - -# if(__has_feature(cxx_rvalue_references)) -# define GLM_CXX11_RVALUE_REFERENCES -# endif - -# if(__has_feature(cxx_static_assert)) -# define GLM_CXX11_STATIC_ASSERT -# endif - -# if(__has_feature(cxx_auto_type)) -# define GLM_CXX11_AUTO_TYPE -# endif - -# if(__has_feature(cxx_strong_enums)) -# define GLM_CXX11_STRONG_ENUMS -# endif - -# if(__has_feature(cxx_trailing_return)) -# define GLM_CXX11_TRAILING_RETURN -# endif - -# if(__has_feature(cxx_unicode_literals)) -# define GLM_CXX11_UNICODE_LITERALS -# endif - -# if(__has_feature(cxx_unrestricted_unions)) -# define GLM_CXX11_UNRESTRICTED_UNIONS -# endif - -# if(__has_feature(cxx_user_literals)) -# define GLM_CXX11_USER_LITERALS -# endif - -# if(__has_feature(cxx_variadic_templates)) -# define GLM_CXX11_VARIADIC_TEMPLATES -# endif - -#endif//(GLM_COMPILER & GLM_COMPILER_CLANG) diff --git a/include/glm/detail/_fixes.hpp b/include/glm/detail/_fixes.hpp deleted file mode 100755 index c957562b..00000000 --- a/include/glm/detail/_fixes.hpp +++ /dev/null @@ -1,30 +0,0 @@ -/// @ref core -/// @file glm/detail/_fixes.hpp - -#include - -//! Workaround for compatibility with other libraries -#ifdef max -#undef max -#endif - -//! Workaround for compatibility with other libraries -#ifdef min -#undef min -#endif - -//! Workaround for Android -#ifdef isnan -#undef isnan -#endif - -//! Workaround for Android -#ifdef isinf -#undef isinf -#endif - -//! Workaround for Chrone Native Client -#ifdef log2 -#undef log2 -#endif - diff --git a/include/glm/detail/_noise.hpp b/include/glm/detail/_noise.hpp deleted file mode 100755 index 89403f4a..00000000 --- a/include/glm/detail/_noise.hpp +++ /dev/null @@ -1,107 +0,0 @@ -/// @ref core -/// @file glm/detail/_noise.hpp - -#pragma once - -#include "../vec2.hpp" -#include "../vec3.hpp" -#include "../vec4.hpp" -#include "../common.hpp" - -namespace glm{ -namespace detail -{ - template - GLM_FUNC_QUALIFIER T mod289(T const & x) - { - return x - floor(x * static_cast(1.0) / static_cast(289.0)) * static_cast(289.0); - } - - template - GLM_FUNC_QUALIFIER T permute(T const & x) - { - return mod289(((x * static_cast(34)) + static_cast(1)) * x); - } - - template - GLM_FUNC_QUALIFIER tvec2 permute(tvec2 const & x) - { - return mod289(((x * static_cast(34)) + static_cast(1)) * x); - } - - template - GLM_FUNC_QUALIFIER tvec3 permute(tvec3 const & x) - { - return mod289(((x * static_cast(34)) + static_cast(1)) * x); - } - - template - GLM_FUNC_QUALIFIER tvec4 permute(tvec4 const & x) - { - return mod289(((x * static_cast(34)) + static_cast(1)) * x); - } -/* - template class vecType> - GLM_FUNC_QUALIFIER vecType permute(vecType const & x) - { - return mod289(((x * T(34)) + T(1)) * x); - } -*/ - template - GLM_FUNC_QUALIFIER T taylorInvSqrt(T const & r) - { - return T(1.79284291400159) - T(0.85373472095314) * r; - } - - template - GLM_FUNC_QUALIFIER tvec2 taylorInvSqrt(tvec2 const & r) - { - return T(1.79284291400159) - T(0.85373472095314) * r; - } - - template - GLM_FUNC_QUALIFIER tvec3 taylorInvSqrt(tvec3 const & r) - { - return T(1.79284291400159) - T(0.85373472095314) * r; - } - - template - GLM_FUNC_QUALIFIER tvec4 taylorInvSqrt(tvec4 const & r) - { - return T(1.79284291400159) - T(0.85373472095314) * r; - } -/* - template class vecType> - GLM_FUNC_QUALIFIER vecType taylorInvSqrt(vecType const & r) - { - return T(1.79284291400159) - T(0.85373472095314) * r; - } -*/ - - template - GLM_FUNC_QUALIFIER tvec2 fade(tvec2 const & t) - { - return (t * t * t) * (t * (t * T(6) - T(15)) + T(10)); - } - - template - GLM_FUNC_QUALIFIER tvec3 fade(tvec3 const & t) - { - return (t * t * t) * (t * (t * T(6) - T(15)) + T(10)); - } - - template - GLM_FUNC_QUALIFIER tvec4 fade(tvec4 const & t) - { - return (t * t * t) * (t * (t * T(6) - T(15)) + T(10)); - } -/* - template class vecType> - GLM_FUNC_QUALIFIER vecType fade(vecType const & t) - { - return (t * t * t) * (t * (t * T(6) - T(15)) + T(10)); - } -*/ -}//namespace detail -}//namespace glm - diff --git a/include/glm/detail/_swizzle.hpp b/include/glm/detail/_swizzle.hpp deleted file mode 100755 index 8e134d90..00000000 --- a/include/glm/detail/_swizzle.hpp +++ /dev/null @@ -1,797 +0,0 @@ -/// @ref core -/// @file glm/detail/_swizzle.hpp - -#pragma once - -namespace glm{ -namespace detail -{ - // Internal class for implementing swizzle operators - template - struct _swizzle_base0 - { - protected: - GLM_FUNC_QUALIFIER T& elem(size_t i){ return (reinterpret_cast(_buffer))[i]; } - GLM_FUNC_QUALIFIER T const& elem(size_t i) const{ return (reinterpret_cast(_buffer))[i]; } - - // Use an opaque buffer to *ensure* the compiler doesn't call a constructor. - // The size 1 buffer is assumed to aligned to the actual members so that the - // elem() - char _buffer[1]; - }; - - template class vecType, int E0, int E1, int E2, int E3, bool Aligned> - struct _swizzle_base1 : public _swizzle_base0 - { - }; - - template class vecType, int E0, int E1, bool Aligned> - struct _swizzle_base1<2, T, P, vecType, E0,E1,-1,-2, Aligned> : public _swizzle_base0 - { - GLM_FUNC_QUALIFIER vecType operator ()() const { return vecType(this->elem(E0), this->elem(E1)); } - }; - - template class vecType, int E0, int E1, int E2, bool Aligned> - struct _swizzle_base1<3, T, P, vecType, E0,E1,E2,-1, Aligned> : public _swizzle_base0 - { - GLM_FUNC_QUALIFIER vecType operator ()() const { return vecType(this->elem(E0), this->elem(E1), this->elem(E2)); } - }; - - template class vecType, int E0, int E1, int E2, int E3, bool Aligned> - struct _swizzle_base1<4, T, P, vecType, E0,E1,E2,E3, Aligned> : public _swizzle_base0 - { - GLM_FUNC_QUALIFIER vecType operator ()() const { return vecType(this->elem(E0), this->elem(E1), this->elem(E2), this->elem(E3)); } - }; - - // Internal class for implementing swizzle operators - /* - Template parameters: - - ValueType = type of scalar values (e.g. float, double) - VecType = class the swizzle is applies to (e.g. tvec3) - N = number of components in the vector (e.g. 3) - E0...3 = what index the n-th element of this swizzle refers to in the unswizzled vec - - DUPLICATE_ELEMENTS = 1 if there is a repeated element, 0 otherwise (used to specialize swizzles - containing duplicate elements so that they cannot be used as r-values). - */ - template class vecType, int E0, int E1, int E2, int E3, int DUPLICATE_ELEMENTS> - struct _swizzle_base2 : public _swizzle_base1::value> - { - GLM_FUNC_QUALIFIER _swizzle_base2& operator= (const T& t) - { - for (int i = 0; i < N; ++i) - (*this)[i] = t; - return *this; - } - - GLM_FUNC_QUALIFIER _swizzle_base2& operator= (vecType const& that) - { - struct op { - GLM_FUNC_QUALIFIER void operator() (T& e, T& t) { e = t; } - }; - _apply_op(that, op()); - return *this; - } - - GLM_FUNC_QUALIFIER void operator -= (vecType const& that) - { - struct op { - GLM_FUNC_QUALIFIER void operator() (T& e, T& t) { e -= t; } - }; - _apply_op(that, op()); - } - - GLM_FUNC_QUALIFIER void operator += (vecType const& that) - { - struct op { - GLM_FUNC_QUALIFIER void operator() (T& e, T& t) { e += t; } - }; - _apply_op(that, op()); - } - - GLM_FUNC_QUALIFIER void operator *= (vecType const& that) - { - struct op { - GLM_FUNC_QUALIFIER void operator() (T& e, T& t) { e *= t; } - }; - _apply_op(that, op()); - } - - GLM_FUNC_QUALIFIER void operator /= (vecType const& that) - { - struct op { - GLM_FUNC_QUALIFIER void operator() (T& e, T& t) { e /= t; } - }; - _apply_op(that, op()); - } - - GLM_FUNC_QUALIFIER T& operator[](size_t i) - { - const int offset_dst[4] = { E0, E1, E2, E3 }; - return this->elem(offset_dst[i]); - } - GLM_FUNC_QUALIFIER T operator[](size_t i) const - { - const int offset_dst[4] = { E0, E1, E2, E3 }; - return this->elem(offset_dst[i]); - } - - protected: - template - GLM_FUNC_QUALIFIER void _apply_op(vecType const& that, U op) - { - // Make a copy of the data in this == &that. - // The copier should optimize out the copy in cases where the function is - // properly inlined and the copy is not necessary. - T t[N]; - for (int i = 0; i < N; ++i) - t[i] = that[i]; - for (int i = 0; i < N; ++i) - op( (*this)[i], t[i] ); - } - }; - - // Specialization for swizzles containing duplicate elements. These cannot be modified. - template class vecType, int E0, int E1, int E2, int E3> - struct _swizzle_base2 : public _swizzle_base1::value> - { - struct Stub {}; - - GLM_FUNC_QUALIFIER _swizzle_base2& operator= (Stub const &) { return *this; } - - GLM_FUNC_QUALIFIER T operator[] (size_t i) const - { - const int offset_dst[4] = { E0, E1, E2, E3 }; - return this->elem(offset_dst[i]); - } - }; - - template class vecType, int E0, int E1, int E2, int E3> - struct _swizzle : public _swizzle_base2 - { - typedef _swizzle_base2 base_type; - - using base_type::operator=; - - GLM_FUNC_QUALIFIER operator vecType () const { return (*this)(); } - }; - -// -// To prevent the C++ syntax from getting entirely overwhelming, define some alias macros -// -#define _GLM_SWIZZLE_TEMPLATE1 template class vecType, int E0, int E1, int E2, int E3> -#define _GLM_SWIZZLE_TEMPLATE2 template class vecType, int E0, int E1, int E2, int E3, int F0, int F1, int F2, int F3> -#define _GLM_SWIZZLE_TYPE1 _swizzle -#define _GLM_SWIZZLE_TYPE2 _swizzle - -// -// Wrapper for a binary operator (e.g. u.yy + v.zy) -// -#define _GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(OPERAND) \ - _GLM_SWIZZLE_TEMPLATE2 \ - GLM_FUNC_QUALIFIER vecType operator OPERAND ( const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE2& b) \ - { \ - return a() OPERAND b(); \ - } \ - _GLM_SWIZZLE_TEMPLATE1 \ - GLM_FUNC_QUALIFIER vecType operator OPERAND ( const _GLM_SWIZZLE_TYPE1& a, const vecType& b) \ - { \ - return a() OPERAND b; \ - } \ - _GLM_SWIZZLE_TEMPLATE1 \ - GLM_FUNC_QUALIFIER vecType operator OPERAND ( const vecType& a, const _GLM_SWIZZLE_TYPE1& b) \ - { \ - return a OPERAND b(); \ - } - -// -// Wrapper for a operand between a swizzle and a binary (e.g. 1.0f - u.xyz) -// -#define _GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(OPERAND) \ - _GLM_SWIZZLE_TEMPLATE1 \ - GLM_FUNC_QUALIFIER vecType operator OPERAND ( const _GLM_SWIZZLE_TYPE1& a, const T& b) \ - { \ - return a() OPERAND b; \ - } \ - _GLM_SWIZZLE_TEMPLATE1 \ - GLM_FUNC_QUALIFIER vecType operator OPERAND ( const T& a, const _GLM_SWIZZLE_TYPE1& b) \ - { \ - return a OPERAND b(); \ - } - -// -// Macro for wrapping a function taking one argument (e.g. abs()) -// -#define _GLM_SWIZZLE_FUNCTION_1_ARGS(RETURN_TYPE,FUNCTION) \ - _GLM_SWIZZLE_TEMPLATE1 \ - GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a) \ - { \ - return FUNCTION(a()); \ - } - -// -// Macro for wrapping a function taking two vector arguments (e.g. dot()). -// -#define _GLM_SWIZZLE_FUNCTION_2_ARGS(RETURN_TYPE,FUNCTION) \ - _GLM_SWIZZLE_TEMPLATE2 \ - GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE2& b) \ - { \ - return FUNCTION(a(), b()); \ - } \ - _GLM_SWIZZLE_TEMPLATE1 \ - GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE1& b) \ - { \ - return FUNCTION(a(), b()); \ - } \ - _GLM_SWIZZLE_TEMPLATE1 \ - GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const typename V& b) \ - { \ - return FUNCTION(a(), b); \ - } \ - _GLM_SWIZZLE_TEMPLATE1 \ - GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const V& a, const _GLM_SWIZZLE_TYPE1& b) \ - { \ - return FUNCTION(a, b()); \ - } - -// -// Macro for wrapping a function take 2 vec arguments followed by a scalar (e.g. mix()). -// -#define _GLM_SWIZZLE_FUNCTION_2_ARGS_SCALAR(RETURN_TYPE,FUNCTION) \ - _GLM_SWIZZLE_TEMPLATE2 \ - GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE2& b, const T& c) \ - { \ - return FUNCTION(a(), b(), c); \ - } \ - _GLM_SWIZZLE_TEMPLATE1 \ - GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE1& b, const T& c) \ - { \ - return FUNCTION(a(), b(), c); \ - } \ - _GLM_SWIZZLE_TEMPLATE1 \ - GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const typename S0::vec_type& b, const T& c)\ - { \ - return FUNCTION(a(), b, c); \ - } \ - _GLM_SWIZZLE_TEMPLATE1 \ - GLM_FUNC_QUALIFIER typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const typename V& a, const _GLM_SWIZZLE_TYPE1& b, const T& c) \ - { \ - return FUNCTION(a, b(), c); \ - } - -}//namespace detail -}//namespace glm - -namespace glm -{ - namespace detail - { - _GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(-) - _GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(*) - _GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(+) - _GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(-) - _GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(*) - _GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(/) - } - - // - // Swizzles are distinct types from the unswizzled type. The below macros will - // provide template specializations for the swizzle types for the given functions - // so that the compiler does not have any ambiguity to choosing how to handle - // the function. - // - // The alternative is to use the operator()() when calling the function in order - // to explicitly convert the swizzled type to the unswizzled type. - // - - //_GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, abs); - //_GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, acos); - //_GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, acosh); - //_GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, all); - //_GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type, any); - - //_GLM_SWIZZLE_FUNCTION_2_ARGS(value_type, dot); - //_GLM_SWIZZLE_FUNCTION_2_ARGS(vec_type, cross); - //_GLM_SWIZZLE_FUNCTION_2_ARGS(vec_type, step); - //_GLM_SWIZZLE_FUNCTION_2_ARGS_SCALAR(vec_type, mix); -} - -#define _GLM_SWIZZLE2_2_MEMBERS(T, P, V, E0,E1) \ - struct { detail::_swizzle<2, T, P, V, 0,0,-1,-2> E0 ## E0; }; \ - struct { detail::_swizzle<2, T, P, V, 0,1,-1,-2> E0 ## E1; }; \ - struct { detail::_swizzle<2, T, P, V, 1,0,-1,-2> E1 ## E0; }; \ - struct { detail::_swizzle<2, T, P, V, 1,1,-1,-2> E1 ## E1; }; - -#define _GLM_SWIZZLE2_3_MEMBERS(T, P, V, E0,E1) \ - struct { detail::_swizzle<3,T, P, V, 0,0,0,-1> E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<3,T, P, V, 0,0,1,-1> E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<3,T, P, V, 0,1,0,-1> E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<3,T, P, V, 0,1,1,-1> E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<3,T, P, V, 1,0,0,-1> E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<3,T, P, V, 1,0,1,-1> E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<3,T, P, V, 1,1,0,-1> E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<3,T, P, V, 1,1,1,-1> E1 ## E1 ## E1; }; - -#define _GLM_SWIZZLE2_4_MEMBERS(T, P, V, E0,E1) \ - struct { detail::_swizzle<4,T, P, V, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; - -#define _GLM_SWIZZLE3_2_MEMBERS(T, P, V, E0,E1,E2) \ - struct { detail::_swizzle<2,T, P, V, 0,0,-1,-2> E0 ## E0; }; \ - struct { detail::_swizzle<2,T, P, V, 0,1,-1,-2> E0 ## E1; }; \ - struct { detail::_swizzle<2,T, P, V, 0,2,-1,-2> E0 ## E2; }; \ - struct { detail::_swizzle<2,T, P, V, 1,0,-1,-2> E1 ## E0; }; \ - struct { detail::_swizzle<2,T, P, V, 1,1,-1,-2> E1 ## E1; }; \ - struct { detail::_swizzle<2,T, P, V, 1,2,-1,-2> E1 ## E2; }; \ - struct { detail::_swizzle<2,T, P, V, 2,0,-1,-2> E2 ## E0; }; \ - struct { detail::_swizzle<2,T, P, V, 2,1,-1,-2> E2 ## E1; }; \ - struct { detail::_swizzle<2,T, P, V, 2,2,-1,-2> E2 ## E2; }; - -#define _GLM_SWIZZLE3_3_MEMBERS(T, P, V ,E0,E1,E2) \ - struct { detail::_swizzle<3, T, P, V, 0,0,0,-1> E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 0,0,1,-1> E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 0,0,2,-1> E0 ## E0 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 0,1,0,-1> E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 0,1,1,-1> E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 0,1,2,-1> E0 ## E1 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 0,2,0,-1> E0 ## E2 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 0,2,1,-1> E0 ## E2 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 0,2,2,-1> E0 ## E2 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 1,0,0,-1> E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 1,0,1,-1> E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 1,0,2,-1> E1 ## E0 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 1,1,0,-1> E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 1,1,1,-1> E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 1,1,2,-1> E1 ## E1 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 1,2,0,-1> E1 ## E2 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 1,2,1,-1> E1 ## E2 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 1,2,2,-1> E1 ## E2 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 2,0,0,-1> E2 ## E0 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 2,0,1,-1> E2 ## E0 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 2,0,2,-1> E2 ## E0 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 2,1,0,-1> E2 ## E1 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 2,1,1,-1> E2 ## E1 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 2,1,2,-1> E2 ## E1 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 2,2,0,-1> E2 ## E2 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 2,2,1,-1> E2 ## E2 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 2,2,2,-1> E2 ## E2 ## E2; }; - -#define _GLM_SWIZZLE3_4_MEMBERS(T, P, V, E0,E1,E2) \ - struct { detail::_swizzle<4,T, P, V, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,0,2> E0 ## E0 ## E0 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,1,2> E0 ## E0 ## E1 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,2,0> E0 ## E0 ## E2 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,2,1> E0 ## E0 ## E2 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,0,2,2> E0 ## E0 ## E2 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,0,2> E0 ## E1 ## E0 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,1,2> E0 ## E1 ## E1 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,2,0> E0 ## E1 ## E2 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,2,1> E0 ## E1 ## E2 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,1,2,2> E0 ## E1 ## E2 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 0,2,0,0> E0 ## E2 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,2,0,1> E0 ## E2 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,2,0,2> E0 ## E2 ## E0 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 0,2,1,0> E0 ## E2 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,2,1,1> E0 ## E2 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,2,1,2> E0 ## E2 ## E1 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 0,2,2,0> E0 ## E2 ## E2 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 0,2,2,1> E0 ## E2 ## E2 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 0,2,2,2> E0 ## E2 ## E2 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,0,2> E1 ## E0 ## E0 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,1,2> E1 ## E0 ## E1 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,2,0> E1 ## E0 ## E2 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,2,1> E1 ## E0 ## E2 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,0,2,2> E1 ## E0 ## E2 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,0,2> E1 ## E1 ## E0 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,1,2> E1 ## E1 ## E1 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,2,0> E1 ## E1 ## E2 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,2,1> E1 ## E1 ## E2 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,1,2,2> E1 ## E1 ## E2 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 1,2,0,0> E1 ## E2 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,2,0,1> E1 ## E2 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,2,0,2> E1 ## E2 ## E0 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 1,2,1,0> E1 ## E2 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,2,1,1> E1 ## E2 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,2,1,2> E1 ## E2 ## E1 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 1,2,2,0> E1 ## E2 ## E2 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 1,2,2,1> E1 ## E2 ## E2 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 1,2,2,2> E1 ## E2 ## E2 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 2,0,0,0> E2 ## E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 2,0,0,1> E2 ## E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 2,0,0,2> E2 ## E0 ## E0 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 2,0,1,0> E2 ## E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 2,0,1,1> E2 ## E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 2,0,1,2> E2 ## E0 ## E1 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 2,0,2,0> E2 ## E0 ## E2 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 2,0,2,1> E2 ## E0 ## E2 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 2,0,2,2> E2 ## E0 ## E2 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 2,1,0,0> E2 ## E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 2,1,0,1> E2 ## E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 2,1,0,2> E2 ## E1 ## E0 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 2,1,1,0> E2 ## E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 2,1,1,1> E2 ## E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 2,1,1,2> E2 ## E1 ## E1 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 2,1,2,0> E2 ## E1 ## E2 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 2,1,2,1> E2 ## E1 ## E2 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 2,1,2,2> E2 ## E1 ## E2 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 2,2,0,0> E2 ## E2 ## E0 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 2,2,0,1> E2 ## E2 ## E0 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 2,2,0,2> E2 ## E2 ## E0 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 2,2,1,0> E2 ## E2 ## E1 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 2,2,1,1> E2 ## E2 ## E1 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 2,2,1,2> E2 ## E2 ## E1 ## E2; }; \ - struct { detail::_swizzle<4,T, P, V, 2,2,2,0> E2 ## E2 ## E2 ## E0; }; \ - struct { detail::_swizzle<4,T, P, V, 2,2,2,1> E2 ## E2 ## E2 ## E1; }; \ - struct { detail::_swizzle<4,T, P, V, 2,2,2,2> E2 ## E2 ## E2 ## E2; }; - -#define _GLM_SWIZZLE4_2_MEMBERS(T, P, V, E0,E1,E2,E3) \ - struct { detail::_swizzle<2,T, P, V, 0,0,-1,-2> E0 ## E0; }; \ - struct { detail::_swizzle<2,T, P, V, 0,1,-1,-2> E0 ## E1; }; \ - struct { detail::_swizzle<2,T, P, V, 0,2,-1,-2> E0 ## E2; }; \ - struct { detail::_swizzle<2,T, P, V, 0,3,-1,-2> E0 ## E3; }; \ - struct { detail::_swizzle<2,T, P, V, 1,0,-1,-2> E1 ## E0; }; \ - struct { detail::_swizzle<2,T, P, V, 1,1,-1,-2> E1 ## E1; }; \ - struct { detail::_swizzle<2,T, P, V, 1,2,-1,-2> E1 ## E2; }; \ - struct { detail::_swizzle<2,T, P, V, 1,3,-1,-2> E1 ## E3; }; \ - struct { detail::_swizzle<2,T, P, V, 2,0,-1,-2> E2 ## E0; }; \ - struct { detail::_swizzle<2,T, P, V, 2,1,-1,-2> E2 ## E1; }; \ - struct { detail::_swizzle<2,T, P, V, 2,2,-1,-2> E2 ## E2; }; \ - struct { detail::_swizzle<2,T, P, V, 2,3,-1,-2> E2 ## E3; }; \ - struct { detail::_swizzle<2,T, P, V, 3,0,-1,-2> E3 ## E0; }; \ - struct { detail::_swizzle<2,T, P, V, 3,1,-1,-2> E3 ## E1; }; \ - struct { detail::_swizzle<2,T, P, V, 3,2,-1,-2> E3 ## E2; }; \ - struct { detail::_swizzle<2,T, P, V, 3,3,-1,-2> E3 ## E3; }; - -#define _GLM_SWIZZLE4_3_MEMBERS(T, P, V, E0,E1,E2,E3) \ - struct { detail::_swizzle<3, T, P, V, 0,0,0,-1> E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 0,0,1,-1> E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 0,0,2,-1> E0 ## E0 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 0,0,3,-1> E0 ## E0 ## E3; }; \ - struct { detail::_swizzle<3, T, P, V, 0,1,0,-1> E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 0,1,1,-1> E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 0,1,2,-1> E0 ## E1 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 0,1,3,-1> E0 ## E1 ## E3; }; \ - struct { detail::_swizzle<3, T, P, V, 0,2,0,-1> E0 ## E2 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 0,2,1,-1> E0 ## E2 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 0,2,2,-1> E0 ## E2 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 0,2,3,-1> E0 ## E2 ## E3; }; \ - struct { detail::_swizzle<3, T, P, V, 0,3,0,-1> E0 ## E3 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 0,3,1,-1> E0 ## E3 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 0,3,2,-1> E0 ## E3 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 0,3,3,-1> E0 ## E3 ## E3; }; \ - struct { detail::_swizzle<3, T, P, V, 1,0,0,-1> E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 1,0,1,-1> E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 1,0,2,-1> E1 ## E0 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 1,0,3,-1> E1 ## E0 ## E3; }; \ - struct { detail::_swizzle<3, T, P, V, 1,1,0,-1> E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 1,1,1,-1> E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 1,1,2,-1> E1 ## E1 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 1,1,3,-1> E1 ## E1 ## E3; }; \ - struct { detail::_swizzle<3, T, P, V, 1,2,0,-1> E1 ## E2 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 1,2,1,-1> E1 ## E2 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 1,2,2,-1> E1 ## E2 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 1,2,3,-1> E1 ## E2 ## E3; }; \ - struct { detail::_swizzle<3, T, P, V, 1,3,0,-1> E1 ## E3 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 1,3,1,-1> E1 ## E3 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 1,3,2,-1> E1 ## E3 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 1,3,3,-1> E1 ## E3 ## E3; }; \ - struct { detail::_swizzle<3, T, P, V, 2,0,0,-1> E2 ## E0 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 2,0,1,-1> E2 ## E0 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 2,0,2,-1> E2 ## E0 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 2,0,3,-1> E2 ## E0 ## E3; }; \ - struct { detail::_swizzle<3, T, P, V, 2,1,0,-1> E2 ## E1 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 2,1,1,-1> E2 ## E1 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 2,1,2,-1> E2 ## E1 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 2,1,3,-1> E2 ## E1 ## E3; }; \ - struct { detail::_swizzle<3, T, P, V, 2,2,0,-1> E2 ## E2 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 2,2,1,-1> E2 ## E2 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 2,2,2,-1> E2 ## E2 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 2,2,3,-1> E2 ## E2 ## E3; }; \ - struct { detail::_swizzle<3, T, P, V, 2,3,0,-1> E2 ## E3 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 2,3,1,-1> E2 ## E3 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 2,3,2,-1> E2 ## E3 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 2,3,3,-1> E2 ## E3 ## E3; }; \ - struct { detail::_swizzle<3, T, P, V, 3,0,0,-1> E3 ## E0 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 3,0,1,-1> E3 ## E0 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 3,0,2,-1> E3 ## E0 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 3,0,3,-1> E3 ## E0 ## E3; }; \ - struct { detail::_swizzle<3, T, P, V, 3,1,0,-1> E3 ## E1 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 3,1,1,-1> E3 ## E1 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 3,1,2,-1> E3 ## E1 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 3,1,3,-1> E3 ## E1 ## E3; }; \ - struct { detail::_swizzle<3, T, P, V, 3,2,0,-1> E3 ## E2 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 3,2,1,-1> E3 ## E2 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 3,2,2,-1> E3 ## E2 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 3,2,3,-1> E3 ## E2 ## E3; }; \ - struct { detail::_swizzle<3, T, P, V, 3,3,0,-1> E3 ## E3 ## E0; }; \ - struct { detail::_swizzle<3, T, P, V, 3,3,1,-1> E3 ## E3 ## E1; }; \ - struct { detail::_swizzle<3, T, P, V, 3,3,2,-1> E3 ## E3 ## E2; }; \ - struct { detail::_swizzle<3, T, P, V, 3,3,3,-1> E3 ## E3 ## E3; }; - -#define _GLM_SWIZZLE4_4_MEMBERS(T, P, V, E0,E1,E2,E3) \ - struct { detail::_swizzle<4, T, P, V, 0,0,0,0> E0 ## E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,0,1> E0 ## E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,0,2> E0 ## E0 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,0,3> E0 ## E0 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,1,0> E0 ## E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,1,1> E0 ## E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,1,2> E0 ## E0 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,1,3> E0 ## E0 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,2,0> E0 ## E0 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,2,1> E0 ## E0 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,2,2> E0 ## E0 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,2,3> E0 ## E0 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,3,0> E0 ## E0 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,3,1> E0 ## E0 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,3,2> E0 ## E0 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,0,3,3> E0 ## E0 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,0,0> E0 ## E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,0,1> E0 ## E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,0,2> E0 ## E1 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,0,3> E0 ## E1 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,1,0> E0 ## E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,1,1> E0 ## E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,1,2> E0 ## E1 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,1,3> E0 ## E1 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,2,0> E0 ## E1 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,2,1> E0 ## E1 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,2,2> E0 ## E1 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,2,3> E0 ## E1 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,3,0> E0 ## E1 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,3,1> E0 ## E1 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,3,2> E0 ## E1 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,1,3,3> E0 ## E1 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,0,0> E0 ## E2 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,0,1> E0 ## E2 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,0,2> E0 ## E2 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,0,3> E0 ## E2 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,1,0> E0 ## E2 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,1,1> E0 ## E2 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,1,2> E0 ## E2 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,1,3> E0 ## E2 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,2,0> E0 ## E2 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,2,1> E0 ## E2 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,2,2> E0 ## E2 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,2,3> E0 ## E2 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,3,0> E0 ## E2 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,3,1> E0 ## E2 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,3,2> E0 ## E2 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,2,3,3> E0 ## E2 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,0,0> E0 ## E3 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,0,1> E0 ## E3 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,0,2> E0 ## E3 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,0,3> E0 ## E3 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,1,0> E0 ## E3 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,1,1> E0 ## E3 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,1,2> E0 ## E3 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,1,3> E0 ## E3 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,2,0> E0 ## E3 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,2,1> E0 ## E3 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,2,2> E0 ## E3 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,2,3> E0 ## E3 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,3,0> E0 ## E3 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,3,1> E0 ## E3 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,3,2> E0 ## E3 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 0,3,3,3> E0 ## E3 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,0,0> E1 ## E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,0,1> E1 ## E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,0,2> E1 ## E0 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,0,3> E1 ## E0 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,1,0> E1 ## E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,1,1> E1 ## E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,1,2> E1 ## E0 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,1,3> E1 ## E0 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,2,0> E1 ## E0 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,2,1> E1 ## E0 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,2,2> E1 ## E0 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,2,3> E1 ## E0 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,3,0> E1 ## E0 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,3,1> E1 ## E0 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,3,2> E1 ## E0 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,0,3,3> E1 ## E0 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,0,0> E1 ## E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,0,1> E1 ## E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,0,2> E1 ## E1 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,0,3> E1 ## E1 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,1,0> E1 ## E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,1,1> E1 ## E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,1,2> E1 ## E1 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,1,3> E1 ## E1 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,2,0> E1 ## E1 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,2,1> E1 ## E1 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,2,2> E1 ## E1 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,2,3> E1 ## E1 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,3,0> E1 ## E1 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,3,1> E1 ## E1 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,3,2> E1 ## E1 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,1,3,3> E1 ## E1 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,0,0> E1 ## E2 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,0,1> E1 ## E2 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,0,2> E1 ## E2 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,0,3> E1 ## E2 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,1,0> E1 ## E2 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,1,1> E1 ## E2 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,1,2> E1 ## E2 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,1,3> E1 ## E2 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,2,0> E1 ## E2 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,2,1> E1 ## E2 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,2,2> E1 ## E2 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,2,3> E1 ## E2 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,3,0> E1 ## E2 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,3,1> E1 ## E2 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,3,2> E1 ## E2 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,2,3,3> E1 ## E2 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,0,0> E1 ## E3 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,0,1> E1 ## E3 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,0,2> E1 ## E3 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,0,3> E1 ## E3 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,1,0> E1 ## E3 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,1,1> E1 ## E3 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,1,2> E1 ## E3 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,1,3> E1 ## E3 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,2,0> E1 ## E3 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,2,1> E1 ## E3 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,2,2> E1 ## E3 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,2,3> E1 ## E3 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,3,0> E1 ## E3 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,3,1> E1 ## E3 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,3,2> E1 ## E3 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 1,3,3,3> E1 ## E3 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,0,0> E2 ## E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,0,1> E2 ## E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,0,2> E2 ## E0 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,0,3> E2 ## E0 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,1,0> E2 ## E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,1,1> E2 ## E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,1,2> E2 ## E0 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,1,3> E2 ## E0 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,2,0> E2 ## E0 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,2,1> E2 ## E0 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,2,2> E2 ## E0 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,2,3> E2 ## E0 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,3,0> E2 ## E0 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,3,1> E2 ## E0 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,3,2> E2 ## E0 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,0,3,3> E2 ## E0 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,0,0> E2 ## E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,0,1> E2 ## E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,0,2> E2 ## E1 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,0,3> E2 ## E1 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,1,0> E2 ## E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,1,1> E2 ## E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,1,2> E2 ## E1 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,1,3> E2 ## E1 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,2,0> E2 ## E1 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,2,1> E2 ## E1 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,2,2> E2 ## E1 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,2,3> E2 ## E1 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,3,0> E2 ## E1 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,3,1> E2 ## E1 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,3,2> E2 ## E1 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,1,3,3> E2 ## E1 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,0,0> E2 ## E2 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,0,1> E2 ## E2 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,0,2> E2 ## E2 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,0,3> E2 ## E2 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,1,0> E2 ## E2 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,1,1> E2 ## E2 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,1,2> E2 ## E2 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,1,3> E2 ## E2 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,2,0> E2 ## E2 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,2,1> E2 ## E2 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,2,2> E2 ## E2 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,2,3> E2 ## E2 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,3,0> E2 ## E2 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,3,1> E2 ## E2 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,3,2> E2 ## E2 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,2,3,3> E2 ## E2 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,0,0> E2 ## E3 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,0,1> E2 ## E3 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,0,2> E2 ## E3 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,0,3> E2 ## E3 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,1,0> E2 ## E3 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,1,1> E2 ## E3 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,1,2> E2 ## E3 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,1,3> E2 ## E3 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,2,0> E2 ## E3 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,2,1> E2 ## E3 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,2,2> E2 ## E3 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,2,3> E2 ## E3 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,3,0> E2 ## E3 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,3,1> E2 ## E3 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,3,2> E2 ## E3 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 2,3,3,3> E2 ## E3 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,0,0> E3 ## E0 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,0,1> E3 ## E0 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,0,2> E3 ## E0 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,0,3> E3 ## E0 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,1,0> E3 ## E0 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,1,1> E3 ## E0 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,1,2> E3 ## E0 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,1,3> E3 ## E0 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,2,0> E3 ## E0 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,2,1> E3 ## E0 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,2,2> E3 ## E0 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,2,3> E3 ## E0 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,3,0> E3 ## E0 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,3,1> E3 ## E0 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,3,2> E3 ## E0 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,0,3,3> E3 ## E0 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,0,0> E3 ## E1 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,0,1> E3 ## E1 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,0,2> E3 ## E1 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,0,3> E3 ## E1 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,1,0> E3 ## E1 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,1,1> E3 ## E1 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,1,2> E3 ## E1 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,1,3> E3 ## E1 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,2,0> E3 ## E1 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,2,1> E3 ## E1 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,2,2> E3 ## E1 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,2,3> E3 ## E1 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,3,0> E3 ## E1 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,3,1> E3 ## E1 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,3,2> E3 ## E1 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,1,3,3> E3 ## E1 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,0,0> E3 ## E2 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,0,1> E3 ## E2 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,0,2> E3 ## E2 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,0,3> E3 ## E2 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,1,0> E3 ## E2 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,1,1> E3 ## E2 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,1,2> E3 ## E2 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,1,3> E3 ## E2 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,2,0> E3 ## E2 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,2,1> E3 ## E2 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,2,2> E3 ## E2 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,2,3> E3 ## E2 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,3,0> E3 ## E2 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,3,1> E3 ## E2 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,3,2> E3 ## E2 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,2,3,3> E3 ## E2 ## E3 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,0,0> E3 ## E3 ## E0 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,0,1> E3 ## E3 ## E0 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,0,2> E3 ## E3 ## E0 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,0,3> E3 ## E3 ## E0 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,1,0> E3 ## E3 ## E1 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,1,1> E3 ## E3 ## E1 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,1,2> E3 ## E3 ## E1 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,1,3> E3 ## E3 ## E1 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,2,0> E3 ## E3 ## E2 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,2,1> E3 ## E3 ## E2 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,2,2> E3 ## E3 ## E2 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,2,3> E3 ## E3 ## E2 ## E3; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,3,0> E3 ## E3 ## E3 ## E0; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,3,1> E3 ## E3 ## E3 ## E1; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,3,2> E3 ## E3 ## E3 ## E2; }; \ - struct { detail::_swizzle<4, T, P, V, 3,3,3,3> E3 ## E3 ## E3 ## E3; }; diff --git a/include/glm/detail/_swizzle_func.hpp b/include/glm/detail/_swizzle_func.hpp deleted file mode 100755 index 4b37edbb..00000000 --- a/include/glm/detail/_swizzle_func.hpp +++ /dev/null @@ -1,696 +0,0 @@ -/// @ref core -/// @file glm/detail/_swizzle_func.hpp - -#pragma once - -#define GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B) \ - SWIZZLED_TYPE A ## B() CONST \ - { \ - return SWIZZLED_TYPE(this->A, this->B); \ - } - -#define GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B, C) \ - SWIZZLED_TYPE A ## B ## C() CONST \ - { \ - return SWIZZLED_TYPE(this->A, this->B, this->C); \ - } - -#define GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B, C, D) \ - SWIZZLED_TYPE A ## B ## C ## D() CONST \ - { \ - return SWIZZLED_TYPE(this->A, this->B, this->C, this->D); \ - } - -#define GLM_SWIZZLE_GEN_VEC2_ENTRY_DEF(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B) \ - template \ - SWIZZLED_TYPE CLASS_TYPE::A ## B() CONST \ - { \ - return SWIZZLED_TYPE(this->A, this->B); \ - } - -#define GLM_SWIZZLE_GEN_VEC3_ENTRY_DEF(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B, C) \ - template \ - SWIZZLED_TYPE CLASS_TYPE::A ## B ## C() CONST \ - { \ - return SWIZZLED_TYPE(this->A, this->B, this->C); \ - } - -#define GLM_SWIZZLE_GEN_VEC4_ENTRY_DEF(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B, C, D) \ - template \ - SWIZZLED_TYPE CLASS_TYPE::A ## B ## C ## D() CONST \ - { \ - return SWIZZLED_TYPE(this->A, this->B, this->C, this->D); \ - } - -#define GLM_MUTABLE - -#define GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, B) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, A) - -#define GLM_SWIZZLE_GEN_REF_FROM_VEC2(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE) \ - GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, x, y) \ - GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, r, g) \ - GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, s, t) - -//GLM_SWIZZLE_GEN_REF_FROM_VEC2(valType, detail::vec2, detail::ref2) - -#define GLM_SWIZZLE_GEN_REF2_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, B) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, C) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, A) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, C) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, A) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, B) - -#define GLM_SWIZZLE_GEN_REF3_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, B, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, C, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, A, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, C, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, A, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, B, A) - -#define GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, A, B, C) \ - GLM_SWIZZLE_GEN_REF3_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B, C) \ - GLM_SWIZZLE_GEN_REF2_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B, C) - -#define GLM_SWIZZLE_GEN_REF_FROM_VEC3(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE) \ - GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, x, y, z) \ - GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, r, g, b) \ - GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, s, t, p) - -//GLM_SWIZZLE_GEN_REF_FROM_VEC3(valType, detail::vec3, detail::ref2, detail::ref3) - -#define GLM_SWIZZLE_GEN_REF2_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, B) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, C) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, D) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, A) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, C) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, D) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, A) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, B) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, D) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, D, A) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, D, B) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, D, C) - -#define GLM_SWIZZLE_GEN_REF3_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, B, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, B, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, C, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, C, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, D, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, D, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, A, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, A, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, C, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, C, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, D, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, D, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, A, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, A, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, B, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, B, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, D, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, D, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, A, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, A, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, B, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, B, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, C, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, C, B) - -#define GLM_SWIZZLE_GEN_REF4_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, C, B, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, C, D, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, D, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, D, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, B, D, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, B, C, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, C, A, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, C, D, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, D, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, D, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, A, D, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, A, C, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, B, A, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, B, D, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, D, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, D, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, A, D, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, A, B, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, C, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, C, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, A, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, A, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, B, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, B, C, A) - -#define GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, A, B, C, D) \ - GLM_SWIZZLE_GEN_REF2_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B, C, D) \ - GLM_SWIZZLE_GEN_REF3_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B, C, D) \ - GLM_SWIZZLE_GEN_REF4_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC4_TYPE, A, B, C, D) - -#define GLM_SWIZZLE_GEN_REF_FROM_VEC4(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE) \ - GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, x, y, z, w) \ - GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, r, g, b, a) \ - GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, s, t, p, q) - -//GLM_SWIZZLE_GEN_REF_FROM_VEC4(valType, detail::vec4, detail::ref2, detail::ref3, detail::ref4) - -#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B) - -#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B) - -#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, B) - -#define GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, A, B) \ - GLM_SWIZZLE_GEN_VEC2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B) \ - GLM_SWIZZLE_GEN_VEC3_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B) \ - GLM_SWIZZLE_GEN_VEC4_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC4_TYPE, A, B) - -#define GLM_SWIZZLE_GEN_VEC_FROM_VEC2(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE) \ - GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, x, y) \ - GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, r, g) \ - GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, s, t) - -//GLM_SWIZZLE_GEN_VEC_FROM_VEC2(valType, detail::vec2, detail::vec2, detail::vec3, detail::vec4) - -#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C) - -#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C) - -#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, C) - -#define GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, A, B, C) \ - GLM_SWIZZLE_GEN_VEC2_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B, C) \ - GLM_SWIZZLE_GEN_VEC3_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B, C) \ - GLM_SWIZZLE_GEN_VEC4_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC4_TYPE, A, B, C) - -#define GLM_SWIZZLE_GEN_VEC_FROM_VEC3(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE) \ - GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, x, y, z) \ - GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, r, g, b) \ - GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, s, t, p) - -//GLM_SWIZZLE_GEN_VEC_FROM_VEC3(valType, detail::vec3, detail::vec2, detail::vec3, detail::vec4) - -#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C) \ - GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D) - -#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, D) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C) \ - GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, D) - -#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, D, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, D, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, D, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, D, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, D, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, D, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, D, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, D, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, D, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, D, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, D, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, D, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, D, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, D, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, D, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, D, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, D, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, D, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, D, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, D, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, D, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, D, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, D, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, D, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, D, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, D, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, D, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, D, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, D) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, D, A) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, D, B) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, D, C) \ - GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, D, D) - -#define GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, A, B, C, D) \ - GLM_SWIZZLE_GEN_VEC2_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B, C, D) \ - GLM_SWIZZLE_GEN_VEC3_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B, C, D) \ - GLM_SWIZZLE_GEN_VEC4_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC4_TYPE, A, B, C, D) - -#define GLM_SWIZZLE_GEN_VEC_FROM_VEC4(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE) \ - GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, x, y, z, w) \ - GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, r, g, b, a) \ - GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, s, t, p, q) - -//GLM_SWIZZLE_GEN_VEC_FROM_VEC4(valType, detail::vec4, detail::vec2, detail::vec3, detail::vec4) diff --git a/include/glm/detail/_vectorize.hpp b/include/glm/detail/_vectorize.hpp deleted file mode 100755 index a08ed34d..00000000 --- a/include/glm/detail/_vectorize.hpp +++ /dev/null @@ -1,131 +0,0 @@ -/// @ref core -/// @file glm/detail/_vectorize.hpp - -#pragma once - -#include "type_vec1.hpp" -#include "type_vec2.hpp" -#include "type_vec3.hpp" -#include "type_vec4.hpp" - -namespace glm{ -namespace detail -{ - template class vecType> - struct functor1{}; - - template - struct functor1 - { - GLM_FUNC_QUALIFIER static tvec1 call(R (*Func) (T x), tvec1 const & v) - { - return tvec1(Func(v.x)); - } - }; - - template - struct functor1 - { - GLM_FUNC_QUALIFIER static tvec2 call(R (*Func) (T x), tvec2 const & v) - { - return tvec2(Func(v.x), Func(v.y)); - } - }; - - template - struct functor1 - { - GLM_FUNC_QUALIFIER static tvec3 call(R (*Func) (T x), tvec3 const & v) - { - return tvec3(Func(v.x), Func(v.y), Func(v.z)); - } - }; - - template - struct functor1 - { - GLM_FUNC_QUALIFIER static tvec4 call(R (*Func) (T x), tvec4 const & v) - { - return tvec4(Func(v.x), Func(v.y), Func(v.z), Func(v.w)); - } - }; - - template class vecType> - struct functor2{}; - - template - struct functor2 - { - GLM_FUNC_QUALIFIER static tvec1 call(T (*Func) (T x, T y), tvec1 const & a, tvec1 const & b) - { - return tvec1(Func(a.x, b.x)); - } - }; - - template - struct functor2 - { - GLM_FUNC_QUALIFIER static tvec2 call(T (*Func) (T x, T y), tvec2 const & a, tvec2 const & b) - { - return tvec2(Func(a.x, b.x), Func(a.y, b.y)); - } - }; - - template - struct functor2 - { - GLM_FUNC_QUALIFIER static tvec3 call(T (*Func) (T x, T y), tvec3 const & a, tvec3 const & b) - { - return tvec3(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z)); - } - }; - - template - struct functor2 - { - GLM_FUNC_QUALIFIER static tvec4 call(T (*Func) (T x, T y), tvec4 const & a, tvec4 const & b) - { - return tvec4(Func(a.x, b.x), Func(a.y, b.y), Func(a.z, b.z), Func(a.w, b.w)); - } - }; - - template class vecType> - struct functor2_vec_sca{}; - - template - struct functor2_vec_sca - { - GLM_FUNC_QUALIFIER static tvec1 call(T (*Func) (T x, T y), tvec1 const & a, T b) - { - return tvec1(Func(a.x, b)); - } - }; - - template - struct functor2_vec_sca - { - GLM_FUNC_QUALIFIER static tvec2 call(T (*Func) (T x, T y), tvec2 const & a, T b) - { - return tvec2(Func(a.x, b), Func(a.y, b)); - } - }; - - template - struct functor2_vec_sca - { - GLM_FUNC_QUALIFIER static tvec3 call(T (*Func) (T x, T y), tvec3 const & a, T b) - { - return tvec3(Func(a.x, b), Func(a.y, b), Func(a.z, b)); - } - }; - - template - struct functor2_vec_sca - { - GLM_FUNC_QUALIFIER static tvec4 call(T (*Func) (T x, T y), tvec4 const & a, T b) - { - return tvec4(Func(a.x, b), Func(a.y, b), Func(a.z, b), Func(a.w, b)); - } - }; -}//namespace detail -}//namespace glm diff --git a/include/glm/detail/dummy.cpp b/include/glm/detail/dummy.cpp deleted file mode 100755 index a519a6dc..00000000 --- a/include/glm/detail/dummy.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/// @ref core -/// @file glm/core/dummy.cpp -/// -/// GLM is a header only library. There is nothing to compile. -/// dummy.cpp exist only a wordaround for CMake file. - -/* -#define GLM_MESSAGES -#include -#include -#include - -struct material -{ - glm::vec4 emission; // Ecm - glm::vec4 ambient; // Acm - glm::vec4 diffuse; // Dcm - glm::vec4 specular; // Scm - float shininess; // Srm -}; - -struct light -{ - glm::vec4 ambient; // Acli - glm::vec4 diffuse; // Dcli - glm::vec4 specular; // Scli - glm::vec4 position; // Ppli - glm::vec4 halfVector; // Derived: Hi - glm::vec3 spotDirection; // Sdli - float spotExponent; // Srli - float spotCutoff; // Crli - // (range: [0.0,90.0], 180.0) - float spotCosCutoff; // Derived: cos(Crli) - // (range: [1.0,0.0],-1.0) - float constantAttenuation; // K0 - float linearAttenuation; // K1 - float quadraticAttenuation;// K2 -}; - - -// Sample 1 -#include // glm::vec3 -#include // glm::cross, glm::normalize - -glm::vec3 computeNormal -( - glm::vec3 const & a, - glm::vec3 const & b, - glm::vec3 const & c -) -{ - return glm::normalize(glm::cross(c - a, b - a)); -} - -typedef unsigned int GLuint; -#define GL_FALSE 0 -void glUniformMatrix4fv(GLuint, int, int, float*){} - -// Sample 2 -#include // glm::vec3 -#include // glm::vec4, glm::ivec4 -#include // glm::mat4 -#include // glm::translate, glm::rotate, glm::scale, glm::perspective -#include // glm::value_ptr -void func(GLuint LocationMVP, float Translate, glm::vec2 const & Rotate) -{ - glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.f); - glm::mat4 ViewTranslate = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -Translate)); - glm::mat4 ViewRotateX = glm::rotate(ViewTranslate, Rotate.y, glm::vec3(-1.0f, 0.0f, 0.0f)); - glm::mat4 View = glm::rotate(ViewRotateX, Rotate.x, glm::vec3(0.0f, 1.0f, 0.0f)); - glm::mat4 Model = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f)); - glm::mat4 MVP = Projection * View * Model; - glUniformMatrix4fv(LocationMVP, 1, GL_FALSE, glm::value_ptr(MVP)); -} - -// Sample 3 -#include // glm::vec2 -#include // glm::packUnorm2x16 -#include // glm::uint -#include // glm::i8vec2, glm::i32vec2 -std::size_t const VertexCount = 4; -// Float quad geometry -std::size_t const PositionSizeF32 = VertexCount * sizeof(glm::vec2); -glm::vec2 const PositionDataF32[VertexCount] = -{ - glm::vec2(-1.0f,-1.0f), - glm::vec2( 1.0f,-1.0f), - glm::vec2( 1.0f, 1.0f), - glm::vec2(-1.0f, 1.0f) - }; -// Half-float quad geometry -std::size_t const PositionSizeF16 = VertexCount * sizeof(glm::uint); -glm::uint const PositionDataF16[VertexCount] = -{ - glm::uint(glm::packUnorm2x16(glm::vec2(-1.0f, -1.0f))), - glm::uint(glm::packUnorm2x16(glm::vec2( 1.0f, -1.0f))), - glm::uint(glm::packUnorm2x16(glm::vec2( 1.0f, 1.0f))), - glm::uint(glm::packUnorm2x16(glm::vec2(-1.0f, 1.0f))) -}; -// 8 bits signed integer quad geometry -std::size_t const PositionSizeI8 = VertexCount * sizeof(glm::i8vec2); -glm::i8vec2 const PositionDataI8[VertexCount] = -{ - glm::i8vec2(-1,-1), - glm::i8vec2( 1,-1), - glm::i8vec2( 1, 1), - glm::i8vec2(-1, 1) -}; -// 32 bits signed integer quad geometry -std::size_t const PositionSizeI32 = VertexCount * sizeof(glm::i32vec2); -glm::i32vec2 const PositionDataI32[VertexCount] = -{ - glm::i32vec2 (-1,-1), - glm::i32vec2 ( 1,-1), - glm::i32vec2 ( 1, 1), - glm::i32vec2 (-1, 1) -}; - -struct intersection -{ - glm::vec4 position; - glm::vec3 normal; -}; -*/ - - -/* -// Sample 4 -#include // glm::vec3 -#include // glm::normalize, glm::dot, glm::reflect -#include // glm::pow -#include // glm::vecRand3 -glm::vec3 lighting -( - intersection const & Intersection, - material const & Material, - light const & Light, - glm::vec3 const & View -) -{ - glm::vec3 Color(0.0f); - glm::vec3 LightVertor(glm::normalize( - Light.position - Intersection.position + - glm::vecRand3(0.0f, Light.inaccuracy)); - - if(!shadow(Intersection.position, Light.position, LightVertor)) - { - float Diffuse = glm::dot(Intersection.normal, LightVector); - if(Diffuse <= 0.0f) - return Color; - if(Material.isDiffuse()) - Color += Light.color() * Material.diffuse * Diffuse; - if(Material.isSpecular()) - { - glm::vec3 Reflect(glm::reflect( - glm::normalize(-LightVector), - glm::normalize(Intersection.normal))); - float Dot = glm::dot(Reflect, View); - float Base = Dot > 0.0f ? Dot : 0.0f; - float Specular = glm::pow(Base, Material.exponent); - Color += Material.specular * Specular; - } - } - return Color; -} -*/ - -/* -template class vecType> -T normalizeDotA(vecType const & x, vecType const & y) -{ - return glm::dot(x, y) * glm::inversesqrt(glm::dot(x, x) * glm::dot(y, y)); -} - -#define GLM_TEMPLATE_GENTYPE typename T, glm::precision P, template class - -template -T normalizeDotB(vecType const & x, vecType const & y) -{ - return glm::dot(x, y) * glm::inversesqrt(glm::dot(x, x) * glm::dot(y, y)); -} - -template -typename vecType::value_type normalizeDotC(vecType const & a, vecType const & b) -{ - return glm::dot(a, b) * glm::inversesqrt(glm::dot(a, a) * glm::dot(b, b)); -} -*/ -int main() -{ -/* - glm::vec1 o(1); - glm::vec2 a(1); - glm::vec3 b(1); - glm::vec4 c(1); - - glm::quat q; - glm::dualquat p; - - glm::mat4 m(1); - - float a0 = normalizeDotA(a, a); - float b0 = normalizeDotB(b, b); - float c0 = normalizeDotC(c, c); -*/ - return 0; -} diff --git a/include/glm/detail/func_common.hpp b/include/glm/detail/func_common.hpp deleted file mode 100755 index 871fed6c..00000000 --- a/include/glm/detail/func_common.hpp +++ /dev/null @@ -1,427 +0,0 @@ -/// @ref core -/// @file glm/detail/func_common.hpp -/// -/// @see GLSL 4.20.8 specification, section 8.3 Common Functions -/// -/// @defgroup core_func_common Common functions -/// @ingroup core -/// -/// These all operate component-wise. The description is per component. - -#pragma once - -#include "setup.hpp" -#include "precision.hpp" -#include "type_int.hpp" -#include "_fixes.hpp" - -namespace glm -{ - /// @addtogroup core_func_common - /// @{ - - /// Returns x if x >= 0; otherwise, it returns -x. - /// - /// @tparam genType floating-point or signed integer; scalar or vector types. - /// - /// @see GLSL abs man page - /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - template - GLM_FUNC_DECL genType abs(genType x); - - template class vecType> - GLM_FUNC_DECL vecType abs(vecType const & x); - - /// Returns 1.0 if x > 0, 0.0 if x == 0, or -1.0 if x < 0. - /// - /// @tparam genType Floating-point or signed integer; scalar or vector types. - /// - /// @see GLSL sign man page - /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - template class vecType> - GLM_FUNC_DECL vecType sign(vecType const & x); - - /// Returns a value equal to the nearest integer that is less then or equal to x. - /// - /// @tparam genType Floating-point scalar or vector types. - /// - /// @see GLSL floor man page - /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - template class vecType> - GLM_FUNC_DECL vecType floor(vecType const & x); - - /// Returns a value equal to the nearest integer to x - /// whose absolute value is not larger than the absolute value of x. - /// - /// @tparam genType Floating-point scalar or vector types. - /// - /// @see GLSL trunc man page - /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - template class vecType> - GLM_FUNC_DECL vecType trunc(vecType const & x); - - /// Returns a value equal to the nearest integer to x. - /// The fraction 0.5 will round in a direction chosen by the - /// implementation, presumably the direction that is fastest. - /// This includes the possibility that round(x) returns the - /// same value as roundEven(x) for all values of x. - /// - /// @tparam genType Floating-point scalar or vector types. - /// - /// @see GLSL round man page - /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - template class vecType> - GLM_FUNC_DECL vecType round(vecType const & x); - - /// Returns a value equal to the nearest integer to x. - /// A fractional part of 0.5 will round toward the nearest even - /// integer. (Both 3.5 and 4.5 for x will return 4.0.) - /// - /// @tparam genType Floating-point scalar or vector types. - /// - /// @see GLSL roundEven man page - /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - /// @see New round to even technique - template class vecType> - GLM_FUNC_DECL vecType roundEven(vecType const & x); - - /// Returns a value equal to the nearest integer - /// that is greater than or equal to x. - /// - /// @tparam genType Floating-point scalar or vector types. - /// - /// @see GLSL ceil man page - /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - template class vecType> - GLM_FUNC_DECL vecType ceil(vecType const & x); - - /// Return x - floor(x). - /// - /// @tparam genType Floating-point scalar or vector types. - /// - /// @see GLSL fract man page - /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - template - GLM_FUNC_DECL genType fract(genType x); - - template class vecType> - GLM_FUNC_DECL vecType fract(vecType const & x); - - /// Modulus. Returns x - y * floor(x / y) - /// for each component in x using the floating point value y. - /// - /// @tparam genType Floating-point scalar or vector types. - /// - /// @see GLSL mod man page - /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - template - GLM_FUNC_DECL genType mod(genType x, genType y); - - template class vecType> - GLM_FUNC_DECL vecType mod(vecType const & x, T y); - - template class vecType> - GLM_FUNC_DECL vecType mod(vecType const & x, vecType const & y); - - /// Returns the fractional part of x and sets i to the integer - /// part (as a whole number floating point value). Both the - /// return value and the output parameter will have the same - /// sign as x. - /// - /// @tparam genType Floating-point scalar or vector types. - /// - /// @see GLSL modf man page - /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - template - GLM_FUNC_DECL genType modf(genType x, genType & i); - - /// Returns y if y < x; otherwise, it returns x. - /// - /// @tparam genType Floating-point or integer; scalar or vector types. - /// - /// @see GLSL min man page - /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - template - GLM_FUNC_DECL genType min(genType x, genType y); - - template class vecType> - GLM_FUNC_DECL vecType min(vecType const & x, T y); - - template class vecType> - GLM_FUNC_DECL vecType min(vecType const & x, vecType const & y); - - /// Returns y if x < y; otherwise, it returns x. - /// - /// @tparam genType Floating-point or integer; scalar or vector types. - /// - /// @see GLSL max man page - /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - template - GLM_FUNC_DECL genType max(genType x, genType y); - - template class vecType> - GLM_FUNC_DECL vecType max(vecType const & x, T y); - - template class vecType> - GLM_FUNC_DECL vecType max(vecType const & x, vecType const & y); - - /// Returns min(max(x, minVal), maxVal) for each component in x - /// using the floating-point values minVal and maxVal. - /// - /// @tparam genType Floating-point or integer; scalar or vector types. - /// - /// @see GLSL clamp man page - /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - template - GLM_FUNC_DECL genType clamp(genType x, genType minVal, genType maxVal); - - template class vecType> - GLM_FUNC_DECL vecType clamp(vecType const & x, T minVal, T maxVal); - - template class vecType> - GLM_FUNC_DECL vecType clamp(vecType const & x, vecType const & minVal, vecType const & maxVal); - - /// If genTypeU is a floating scalar or vector: - /// Returns x * (1.0 - a) + y * a, i.e., the linear blend of - /// x and y using the floating-point value a. - /// The value for a is not restricted to the range [0, 1]. - /// - /// If genTypeU is a boolean scalar or vector: - /// Selects which vector each returned component comes - /// from. For a component of that is false, the - /// corresponding component of x is returned. For a - /// component of a that is true, the corresponding - /// component of y is returned. Components of x and y that - /// are not selected are allowed to be invalid floating point - /// values and will have no effect on the results. Thus, this - /// provides different functionality than - /// genType mix(genType x, genType y, genType(a)) - /// where a is a Boolean vector. - /// - /// @see GLSL mix man page - /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - /// - /// @param[in] x Value to interpolate. - /// @param[in] y Value to interpolate. - /// @param[in] a Interpolant. - /// - /// @tparam genTypeT Floating point scalar or vector. - /// @tparam genTypeU Floating point or boolean scalar or vector. It can't be a vector if it is the length of genTypeT. - /// - /// @code - /// #include - /// ... - /// float a; - /// bool b; - /// glm::dvec3 e; - /// glm::dvec3 f; - /// glm::vec4 g; - /// glm::vec4 h; - /// ... - /// glm::vec4 r = glm::mix(g, h, a); // Interpolate with a floating-point scalar two vectors. - /// glm::vec4 s = glm::mix(g, h, b); // Teturns g or h; - /// glm::dvec3 t = glm::mix(e, f, a); // Types of the third parameter is not required to match with the first and the second. - /// glm::vec4 u = glm::mix(g, h, r); // Interpolations can be perform per component with a vector for the last parameter. - /// @endcode - template class vecType> - GLM_FUNC_DECL vecType mix(vecType const & x, vecType const & y, vecType const & a); - - template class vecType> - GLM_FUNC_DECL vecType mix(vecType const & x, vecType const & y, U a); - - template - GLM_FUNC_DECL genTypeT mix(genTypeT x, genTypeT y, genTypeU a); - - /// Returns 0.0 if x < edge, otherwise it returns 1.0 for each component of a genType. - /// - /// @see GLSL step man page - /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - template - GLM_FUNC_DECL genType step(genType edge, genType x); - - /// Returns 0.0 if x < edge, otherwise it returns 1.0. - /// - /// @see GLSL step man page - /// @see GLSL 4.20.8 specification, section 8.3 Common Functions - template