Browse Source

Updated to latest ocornut imgui.

Branimir Karadžić 11 years ago
parent
commit
bbeb0a3ffe

File diff suppressed because it is too large
+ 331 - 160
3rdparty/ocornut-imgui/imgui.cpp


+ 151 - 134
3rdparty/ocornut-imgui/imgui.h

@@ -1,4 +1,4 @@
-// ImGui library v1.21 wip
+// ImGui library v1.30 wip
 // See .cpp file for commentary.
 // See ImGui::ShowTestWindow() for sample code.
 // Read 'Programmer guide' in .cpp for notes on how to setup ImGui in your codebase.
@@ -8,6 +8,7 @@
 
 struct ImDrawList;
 struct ImFont;
+struct ImFontAtlas;
 struct ImGuiAabb;
 struct ImGuiIO;
 struct ImGuiStorage;
@@ -31,8 +32,9 @@ struct ImGuiWindow;
 #endif
 
 typedef unsigned int ImU32;
-typedef unsigned short ImWchar;     // hold a character for display
-typedef ImU32 ImGuiID;              // hold widget unique ID
+typedef unsigned short ImWchar;     // character for display
+typedef void* ImTextureID;          // user data to refer to a texture (e.g. store your texture handle/id)
+typedef ImU32 ImGuiID;              // unique ID used by widgets (typically hashed from a stack of string)
 typedef int ImGuiCol;               // enum ImGuiCol_
 typedef int ImGuiStyleVar;          // enum ImGuiStyleVar_
 typedef int ImGuiKey;               // enum ImGuiKey_
@@ -40,7 +42,7 @@ typedef int ImGuiColorEditMode;     // enum ImGuiColorEditMode_
 typedef int ImGuiWindowFlags;       // enum ImGuiWindowFlags_
 typedef int ImGuiSetCondition;      // enum ImGuiSetCondition_
 typedef int ImGuiInputTextFlags;    // enum ImGuiInputTextFlags_
-struct ImGuiTextEditCallbackData;
+struct ImGuiTextEditCallbackData;   // for advanced uses of InputText()
 
 struct ImVec2
 {
@@ -72,7 +74,7 @@ namespace ImGui
     IMGUI_API void*       MemRealloc(void* ptr, size_t sz);
 }
 
-// std::vector<> like class to avoid dragging dependencies (also: windows implementation of STL with debug enabled is absurdly slow, so let's bypass it so our code runs fast in debug). 
+// std::vector<> like class to avoid dragging dependencies (also: windows implementation of STL with debug enabled is absurdly slow, so let's bypass it so our code runs fast in debug).
 // Use '#define ImVector std::vector' if you want to use the STL type or your own type.
 // Our implementation does NOT call c++ constructors! because the data types we use don't need them (but that could be added as well). Only provide the minimum functionalities we need.
 #ifndef ImVector
@@ -106,10 +108,10 @@ public:
     inline const_iterator       begin() const                   { return Data; }
     inline iterator             end()                           { return Data + Size; }
     inline const_iterator       end() const                     { return Data + Size; }
-    inline value_type&          front()                         { return at(0); }
-    inline const value_type&    front() const                   { return at(0); }
-    inline value_type&          back()                          { IM_ASSERT(Size > 0); return at(Size-1); }
-    inline const value_type&    back() const                    { IM_ASSERT(Size > 0); return at(Size-1); }
+    inline value_type&          front()                         { IM_ASSERT(Size > 0); return Data[0]; }
+    inline const value_type&    front() const                   { IM_ASSERT(Size > 0); return Data[0]; }
+    inline value_type&          back()                          { IM_ASSERT(Size > 0); return Data[Size-1]; }
+    inline const value_type&    back() const                    { IM_ASSERT(Size > 0); return Data[Size-1]; }
     inline void                 swap(ImVector<T>& rhs)          { const size_t rhs_size = rhs.Size; rhs.Size = Size; Size = rhs_size; const size_t rhs_cap = rhs.Capacity; rhs.Capacity = Capacity; Capacity = rhs_cap; value_type* rhs_data = rhs.Data; rhs.Data = Data; Data = rhs_data; }
 
     inline void                 reserve(size_t new_capacity)    { Data = (value_type*)ImGui::MemRealloc(Data, new_capacity * sizeof(value_type)); Capacity = new_capacity; }
@@ -129,7 +131,7 @@ public:
 // - struct ImGuiTextBuffer             // Text buffer for logging/accumulating text
 // - struct ImGuiStorage                // Custom key value storage (if you need to alter open/close states manually)
 // - struct ImDrawList                  // Draw command list
-// - struct ImFont                      // Bitmap font loader
+// - struct ImFont                      // TTF font loader, bake glyphs into bitmap
 
 // ImGui End-user API
 // In a namespace so that user can add extra functions (e.g. Value() helpers for your vector or common types)
@@ -174,16 +176,21 @@ namespace ImGui
     IMGUI_API void          SetStateStorage(ImGuiStorage* tree);                                // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it).
     IMGUI_API ImGuiStorage* GetStateStorage();
 
-    IMGUI_API void          PushItemWidth(float item_width);                                    // width of items for the common item+label case. default to ~2/3 of windows width.
-    IMGUI_API void          PopItemWidth();
-    IMGUI_API float         GetItemWidth();
-    IMGUI_API void          PushAllowKeyboardFocus(bool v);                                     // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets.
-    IMGUI_API void          PopAllowKeyboardFocus();
+    // Parameters stacks (shared)
+    IMGUI_API void          PushFont(ImFont* font);                                             // use NULL as a shortcut to push default font
+    IMGUI_API void          PopFont();
     IMGUI_API void          PushStyleColor(ImGuiCol idx, const ImVec4& col);
     IMGUI_API void          PopStyleColor(int count = 1);
     IMGUI_API void          PushStyleVar(ImGuiStyleVar idx, float val);
     IMGUI_API void          PushStyleVar(ImGuiStyleVar idx, const ImVec2& val);
     IMGUI_API void          PopStyleVar(int count = 1);
+
+    // Parameters stacks (current window)
+    IMGUI_API void          PushItemWidth(float item_width);                                    // width of items for the common item+label case. default to ~2/3 of windows width.
+    IMGUI_API void          PopItemWidth();
+    IMGUI_API float         GetItemWidth();
+    IMGUI_API void          PushAllowKeyboardFocus(bool v);                                     // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets.
+    IMGUI_API void          PopAllowKeyboardFocus();
     IMGUI_API void          PushTextWrapPos(float wrap_pos_x = 0.0f);                           // word-wrapping for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space.
     IMGUI_API void          PopTextWrapPos();
 
@@ -230,12 +237,14 @@ namespace ImGui
     IMGUI_API void          TextWrapped(const char* fmt, ...);                                  // shortcut for PushTextWrapPos(0.0f); Text(fmt, ...); PopTextWrapPos();
     IMGUI_API void          TextWrappedV(const char* fmt, va_list args);
     IMGUI_API void          TextUnformatted(const char* text, const char* text_end = NULL);     // doesn't require null terminated string if 'text_end' is specified. no copy done to any bounded stack buffer, recommended for long chunks of text.
-    IMGUI_API void          LabelText(const char* label, const char* fmt, ...);                 // display text+label aligned the same way as value+label widgets 
+    IMGUI_API void          LabelText(const char* label, const char* fmt, ...);                 // display text+label aligned the same way as value+label widgets
     IMGUI_API void          LabelTextV(const char* label, const char* fmt, va_list args);
     IMGUI_API void          BulletText(const char* fmt, ...);
     IMGUI_API void          BulletTextV(const char* fmt, va_list args);
-    IMGUI_API bool          Button(const char* label, ImVec2 size = ImVec2(0,0), bool repeat_when_held = false);
+    IMGUI_API bool          Button(const char* label, const ImVec2& size = ImVec2(0,0), bool repeat_when_held = false);
     IMGUI_API bool          SmallButton(const char* label);
+    IMGUI_API bool          InvisibleButton(const char* str_id, const ImVec2& size);
+    IMGUI_API void          Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), ImU32 tint_col = 0xFFFFFFFF, ImU32 border_col = 0x00000000);
     IMGUI_API bool          CollapsingHeader(const char* label, const char* str_id = NULL, const bool display_frame = true, const bool default_open = false);
     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. 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);
@@ -294,8 +303,8 @@ namespace ImGui
     IMGUI_API void          LogText(const char* fmt, ...);                                      // pass text data straight to log (without being displayed)
 
     // Utilities
-    IMGUI_API bool          IsItemHovered();                                                    // was the last item active area hovered by mouse?
-    IMGUI_API bool          IsItemFocused();                                                    // was the last item focused for keyboard input?
+    IMGUI_API bool          IsItemHovered();                                                    // was the last item hovered by mouse?
+    IMGUI_API bool          IsItemActive();                                                     // was the last item active? (e.g. button being held, text field being edited- items that don't interact will always return false)
     IMGUI_API ImVec2        GetItemBoxMin();                                                    // get bounding box of last item
     IMGUI_API ImVec2        GetItemBoxMax();                                                    // get bounding box of last item
     IMGUI_API bool          IsClipped(const ImVec2& item_size);                                 // to perform coarse clipping on user's side (as an optimization)
@@ -310,9 +319,11 @@ namespace ImGui
     IMGUI_API float         GetTime();
     IMGUI_API int           GetFrameCount();
     IMGUI_API const char*   GetStyleColName(ImGuiCol idx);
-    IMGUI_API void          GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, const void** png_data, unsigned int* png_size);
     IMGUI_API ImVec2        CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f);
 
+    // Obsolete (will be removed)
+    IMGUI_API void          GetDefaultFontData(const void** fnt_data, unsigned int* fnt_size, const void** png_data, unsigned int* png_size);
+
 } // namespace ImGui
 
 // Flags for ImGui::Begin()
@@ -426,7 +437,7 @@ enum ImGuiStyleVar_
     ImGuiStyleVar_FrameRounding,     // float
     ImGuiStyleVar_ItemSpacing,       // ImVec2
     ImGuiStyleVar_ItemInnerSpacing,  // ImVec2
-    ImGuiStyleVar_TreeNodeSpacing,   // float
+    ImGuiStyleVar_TreeNodeSpacing    // float
 };
 
 // Enumeration for ColorEditMode()
@@ -445,7 +456,7 @@ enum ImGuiSetCondition_
 {
     ImGuiSetCondition_Always              = 1 << 0, // Set the variable
     ImGuiSetCondition_FirstUseThisSession = 1 << 1, // Only set the variable on the first call for this window (once per session)
-    ImGuiSetCondition_FirstUseEver        = 1 << 2, // Only set the variable if the window doesn't exist in the .ini file
+    ImGuiSetCondition_FirstUseEver        = 1 << 2  // Only set the variable if the window doesn't exist in the .ini file
 };
 
 struct ImGuiStyle
@@ -477,28 +488,27 @@ struct ImGuiIO
     // Settings (fill once)                 // Default value:
     //------------------------------------------------------------------
 
-    ImVec2      DisplaySize;                // <unset>                  // 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 .ini file, in seconds.
-    const char* IniFilename;                // = "imgui.ini"            // Path to .ini file. NULL to disable .ini saving.
-    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.
-    int         KeyMap[ImGuiKey_COUNT];     // <unset>                  // Map of indices into the KeysDown[512] entries array
-    ImFont*     Font;                       // <auto>                   // Font (also see 'Settings' fields inside ImFont structure for details)
-    float       FontGlobalScale;            // = 1.0f                   // Global scale all fonts
-    bool        FontAllowUserScaling;       // = false                  // Allow user scaling text of individual window with CTRL+Wheel.
-    float       PixelCenterOffset;          // = 0.0f                   // Try to set to 0.5f or 0.375f if rendering is blurry
-
-    void*       UserData;                   // = NULL                   // Store your own data for retrieval by callbacks.
+    ImVec2        DisplaySize;              // <unset>              // 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 .ini file, in seconds.
+    const char*   IniFilename;              // = "imgui.ini"        // Path to .ini file. NULL to disable .ini saving.
+    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.
+    int           KeyMap[ImGuiKey_COUNT];   // <unset>              // Map of indices into the KeysDown[512] entries array
+    void*         UserData;                 // = NULL               // Store your own data for retrieval by callbacks.
+
+    ImFontAtlas*  Fonts;                    // <auto>               // Load and assemble one or more fonts into a single tightly packed texture. Output to Fonts array.
+    float         FontGlobalScale;          // = 1.0f               // Global scale all fonts
+    bool          FontAllowUserScaling;     // = false              // Allow user scaling text of individual window with CTRL+Wheel.
 
     //------------------------------------------------------------------
     // User Functions
     //------------------------------------------------------------------
 
-    // REQUIRED: rendering function. 
+    // REQUIRED: rendering function.
     // See example code if you are unsure of how to implement this.
-    void        (*RenderDrawListsFn)(ImDrawList** const draw_lists, int count);      
+    void        (*RenderDrawListsFn)(ImDrawList** const draw_lists, int count);
 
     // Optional: access OS clipboard (default to use native Win32 clipboard on Windows, otherwise use a ImGui private clipboard)
     // Override to access OS clipboard on other architectures.
@@ -519,7 +529,7 @@ struct ImGuiIO
 
     ImVec2      MousePos;                   // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.)
     bool        MouseDown[5];               // Mouse buttons. ImGui itself only uses button 0 (left button) but you can use others as storage for convenience.
-    float       MouseWheel;                 // Mouse wheel: 1 unit scrolls about 5 lines text.  
+    float       MouseWheel;                 // Mouse wheel: 1 unit scrolls about 5 lines text.
     bool        KeyCtrl;                    // Keyboard modifier pressed: Control
     bool        KeyShift;                   // Keyboard modifier pressed: Shift
     bool        KeysDown[512];              // Keyboard keys that are pressed (in whatever order user naturally has access to keyboard data)
@@ -548,7 +558,7 @@ struct ImGuiIO
     float       MouseDownTime[5];
     float       KeysDownTime[512];
 
-    IMGUI_API ImGuiIO();
+    IMGUI_API   ImGuiIO();
 };
 
 //-----------------------------------------------------------------------------
@@ -628,18 +638,18 @@ struct ImGuiTextBuffer
 // - You want to store custom debug data easily without adding or editing structures in your code.
 struct ImGuiStorage
 {
-    struct Pair 
-    { 
-        ImGuiID key; 
-        union { int val_i; float val_f; };        
-        Pair(ImGuiID _key, int _val_i) { key = _key; val_i = _val_i; } 
-        Pair(ImGuiID _key, float _val_f) { key = _key; val_f = _val_f; } 
+    struct Pair
+    {
+        ImGuiID key;
+        union { int val_i; float val_f; };
+        Pair(ImGuiID _key, int _val_i) { key = _key; val_i = _val_i; }
+        Pair(ImGuiID _key, float _val_f) { key = _key; val_f = _val_f; }
     };
     ImVector<Pair>    Data;
 
     // - Get***() functions find pair, never add/allocate. Pairs are sorted so a query is O(log N)
     // - Set***() functions find pair, insertion on demand if missing.
-    // - Get***Ptr() functions find pair, insertion on demand if missing, return pointer. Useful if you intend to do Get+Set. 
+    // - Get***Ptr() functions find pair, insertion on demand if missing, return pointer. Useful if you intend to do Get+Set.
     //   A typical use case where this is very convenient:
     //      float* pvar = ImGui::GetIntPtr(key); ImGui::SliderInt("var", pvar, 0, 100); some_var += *pvar;
     // - Sorted insertion is costly but should amortize. A typical frame shouldn't need to insert any new pair.
@@ -656,7 +666,7 @@ struct ImGuiStorage
 // Shared state of InputText(), passed to callback when a ImGuiInputTextFlags_Callback* flag is used.
 struct ImGuiTextEditCallbackData
 {
-    ImGuiKey            EventKey;       // Key pressed (Up/Down/TAB)        // Read-only    
+    ImGuiKey            EventKey;       // Key pressed (Up/Down/TAB)        // Read-only
     char*               Buf;            // Current text                     // Read-write (pointed data only)
     size_t              BufSize;        //                                  // Read-only
     bool                BufDirty;       // Set if you modify Buf directly   // Write
@@ -673,13 +683,14 @@ struct ImGuiTextEditCallbackData
 
 //-----------------------------------------------------------------------------
 // Draw List
-// Hold a series of drawing commands. The user provide a renderer for ImDrawList
+// Hold a series of drawing commands. The user provides a renderer for ImDrawList
 //-----------------------------------------------------------------------------
 
 struct ImDrawCmd
 {
     unsigned int    vtx_count;
     ImVec4          clip_rect;
+    ImTextureID     texture_id;     // Copy of user-provided 'TexID' from ImFont or passed to Image*() functions. Ignore if not using images or multiple fonts.
 };
 
 #ifndef IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT
@@ -710,19 +721,25 @@ struct ImDrawList
     ImVector<ImDrawVert>    vtx_buffer;         // each command consume ImDrawCmd::vtx_count of those
 
     // [Internal to ImGui]
-    ImVector<ImVec4>        clip_rect_stack;    // [internal] clip rect stack while building the command-list (so text command can perform clipping early on)
+    ImVector<ImVec4>        clip_rect_stack;    // [internal]
+    ImVector<ImTextureID>   texture_id_stack;   // [internal]
     ImDrawVert*             vtx_write;          // [internal] point within vtx_buffer after each add command (to avoid using the ImVector<> operators too much)
 
     ImDrawList() { Clear(); }
 
     IMGUI_API void  Clear();
+    IMGUI_API void  SetClipRect(const ImVec4& clip_rect);
     IMGUI_API void  PushClipRect(const ImVec4& clip_rect);
     IMGUI_API void  PopClipRect();
+    IMGUI_API void  SetTextureID(const ImTextureID& texture_id);
+    IMGUI_API void  PushTextureID(const ImTextureID& texture_id);
+    IMGUI_API void  PopTextureID();
     IMGUI_API void  ReserveVertices(unsigned int vtx_count);
     IMGUI_API void  AddVtx(const ImVec2& pos, ImU32 col);
+    IMGUI_API void  AddVtxUV(const ImVec2& pos, ImU32 col, const ImVec2& uv);
     IMGUI_API void  AddVtxLine(const ImVec2& a, const ImVec2& b, ImU32 col);
 
-    // Primitives   
+    // Primitives
     IMGUI_API void  AddLine(const ImVec2& a, const ImVec2& b, ImU32 col);
     IMGUI_API void  AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners=0x0F);
     IMGUI_API void  AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners=0x0F);
@@ -731,99 +748,99 @@ struct ImDrawList
     IMGUI_API void  AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12);
     IMGUI_API void  AddArc(const ImVec2& center, float rad, ImU32 col, int a_min, int a_max, bool tris = false, const ImVec2& third_point_offset = ImVec2(0,0));
     IMGUI_API void  AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f);
+    IMGUI_API void  AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv0, const ImVec2& uv1, ImU32 col);
 };
 
-// Bitmap font data loader & renderer into vertices
-// Using the .fnt format exported by BMFont
-//  - tool: http://www.angelcode.com/products/bmfont
-//  - file-format: http://www.angelcode.com/products/bmfont/doc/file_format.html
-// Assume valid file data (won't handle invalid/malicious data)
-// Handle a subset of the options, namely:
-//  - kerning pair are not supported (because some ImGui code does per-character CalcTextSize calls, need to turn it into something more state-ful to allow for kerning)
-struct ImFont
+// Load and rasterize multiple TTF fonts into a same texture.
+// Sharing a texture for multiple fonts allows us to reduce the number of draw calls during rendering.
+// We also add custom graphic data into the texture that serves for ImGui.
+//  1. (Optional) Call AddFont*** functions. If you don't call any, the default font will be loaded for you.
+//  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.
+//  5. Call ClearPixelsData() to free textures memory on the heap.
+struct ImFontAtlas
 {
-    struct FntInfo;
-    struct FntCommon;
-    struct FntGlyph;
-    struct FntKerning;
-
-    // Settings
-    float                       Scale;              // = 1.0f          // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale()
-    ImVec2                      DisplayOffset;      // = (0.0f,0.0f)   // Offset font rendering by xx pixels
-    ImVec2                      TexUvForWhite;      // = (0.0f,0.0f)   // Font texture must have a white pixel at this UV coordinate. Adjust if you are using custom texture.
-    ImWchar                     FallbackChar;       // = '?'           // Replacement glyph is one isn't found.
-
-    // Data
-    unsigned char*              Data;               // Raw data, content of .fnt file
-    size_t                      DataSize;           //
-    bool                        DataOwned;          // 
-    const FntInfo*              Info;               // (point into raw data)
-    const FntCommon*            Common;             // (point into raw data)
-    const FntGlyph*             Glyphs;             // (point into raw data)
-    size_t                      GlyphsCount;        //
-    const FntKerning*           Kerning;            // (point into raw data) - NB: kerning is unsupported
-    size_t                      KerningCount;       //
-    ImVector<const char*>       Filenames;          // (point into raw data)
-    ImVector<int>               IndexLookup;        // (built)
-    const FntGlyph*             FallbackGlyph;      // == FindGlyph(FontFallbackChar)
-
-    IMGUI_API ImFont();
-    IMGUI_API ~ImFont()         { Clear(); }
-
-    IMGUI_API bool              LoadFromMemory(const void* data, size_t data_size);
-    IMGUI_API bool              LoadFromFile(const char* filename);
+    IMGUI_API ImFontAtlas();
+    IMGUI_API ~ImFontAtlas();
+    IMGUI_API ImFont*           AddFontDefault();
+    IMGUI_API ImFont*           AddFontFromFileTTF(const char* filename, float size_pixels, const ImWchar* glyph_ranges = NULL, int font_no = 0);
+    IMGUI_API ImFont*           AddFontFromMemoryTTF(void* in_ttf_data, size_t in_ttf_data_size, float size_pixels, const ImWchar* glyph_ranges = NULL, int font_no = 0); // Pass ownership of 'in_ttf_data' memory.
+    IMGUI_API void              ClearTexData();             // Saves RAM once the texture has been copied to graphics memory.
     IMGUI_API void              Clear();
-    IMGUI_API void              BuildLookupTable();
-    IMGUI_API const FntGlyph*   FindGlyph(unsigned short c) const;
-    IMGUI_API bool              IsLoaded() const { return Info != NULL && Common != NULL && Glyphs != NULL; }
 
-    // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
-    // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.
-    IMGUI_API ImVec2            CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8
-    IMGUI_API ImVec2            CalcTextSizeW(float size, float max_width, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL) const;                 // wchar
-    IMGUI_API void              RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, ImDrawVert*& out_vertices, float wrap_width = 0.0f) const;
-
-    IMGUI_API const char*       CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const;
-
-#pragma pack(push, 1)
-    struct FntInfo
-    {
-        signed short    FontSize;
-        unsigned char   BitField;       // bit 0: smooth, bit 1: unicode, bit 2: italic, bit 3: bold, bit 4: fixedHeight, bits 5-7: reserved
-        unsigned char   CharSet;
-        unsigned short  StretchH;
-        unsigned char   AA;
-        unsigned char   PaddingUp, PaddingRight, PaddingDown, PaddingLeft;
-        unsigned char   SpacingHoriz, SpacingVert, Outline;
-        //char          FontName[];
-    };
-
-    struct FntCommon
-    {
-        unsigned short  LineHeight, Base;
-        unsigned short  ScaleW, ScaleH;
-        unsigned short  Pages;
-        unsigned char   BitField;
-        unsigned char   Channels[4];
-    };
+    // Retrieve texture data
+    // User is in charge of copying the pixels into graphics memory, then call SetTextureUserID()
+    // After loading the texture into your graphic system, store your texture handle in 'TexID' (ignore if you aren't using multiple fonts nor images)
+    // RGBA32 format is provided for convenience and high compatibility, but note that all RGB pixels are white, so 75% of the memory is wasted.
+    // Pitch = Width * BytesPerPixels
+    IMGUI_API void              GetTexDataAsAlpha8(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL);  // 1 byte per-pixel
+    IMGUI_API void              GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL);  // 4 bytes-per-pixel
+    IMGUI_API void              SetTexID(void* id)  { TexID = id; }
+
+    // Helpers to retrieve list of common Unicode ranges (2 value per range, values are inclusive, zero-terminated list)
+    // (Those functions could be static, aren't so simple use case doesn't have to refer to the ImFontAtlas:: type ever if in their code)
+    IMGUI_API const ImWchar*    GetGlyphRangesDefault();    // Basic Latin, Extended Latin
+    IMGUI_API const ImWchar*    GetGlyphRangesJapanese();   // Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs
+    IMGUI_API const ImWchar*    GetGlyphRangesChinese();    // Japanese + full set of about 21000 CJK Unified Ideographs
+
+    // Members
+    // (Access texture data via GetTexData*() calls which will setup a default font for you.)
+    void*                       TexID;              // User data to refer to the texture once it has been uploaded to user's graphic systems. It ia passed back to you during rendering.
+    unsigned char*              TexPixelsAlpha8;    // 1 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight
+    unsigned int*               TexPixelsRGBA32;    // 4 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight * 4
+    int                         TexWidth;
+    int                         TexHeight;
+    ImVec2                      TexExtraDataPos;    // Position of our rectangle where we draw non-font graphics
+    ImVec2                      TexUvWhitePixel;    // Texture coordinates to a white pixel (part of the TexExtraData block)
+    ImVector<ImFont*>           Fonts;
+
+    // Private
+    struct ImFontAtlasData;
+    ImVector<ImFontAtlasData*>  InputData;          // Internal data
+    IMGUI_API bool              Build();            // Build pixels data. This is automatically for you by the GetTexData*** functions.
+    IMGUI_API void              ClearInputData();   // Clear the input TTF data.
+};
 
-    struct FntGlyph
+// TTF font loading and rendering
+// ImFontAtlas automatically loads a default embedded font for you when you call GetTexDataAsAlpha8() or GetTexDataAsRGBA32().
+// Kerning isn't supported. At the moment some ImGui code does per-character CalcTextSize calls, need something more state-ful.
+struct ImFont
+{
+    // Members: Settings
+    float               FontSize;           // <user set>      // Height of characters, set during loading (don't change after loading)
+    float               Scale;              // = 1.0f          // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale()
+    ImVec2              DisplayOffset;      // = (0.0f,0.0f)   // Offset font rendering by xx pixels
+    ImWchar             FallbackChar;       // = '?'           // Replacement glyph if one isn't found.
+
+    // Members: Runtime data
+    struct Glyph
     {
-        unsigned int    Id;
-        unsigned short  X, Y, Width, Height;
-        signed short    XOffset, YOffset;
+        ImWchar         Codepoint;
         signed short    XAdvance;
-        unsigned char   Page;
-        unsigned char   Channel;
+        signed short    Width, Height;
+        signed short    XOffset, YOffset;
+        float           U0, V0, U1, V1;     // Texture coordinates
     };
+    ImFontAtlas*        ContainerAtlas;     // What we has been loaded into
+    ImVector<Glyph>     Glyphs;
+    ImVector<int>       IndexLookup;        // Index glyphs by Unicode code-point
+    const Glyph*        FallbackGlyph;      // == FindGlyph(FontFallbackChar)
 
-    struct FntKerning
-    {
-        unsigned int    IdFirst;
-        unsigned int    IdSecond;
-        signed short    Amount;
-    };
-#pragma pack(pop)
+    // Methods
+    IMGUI_API ImFont();
+    IMGUI_API ~ImFont() { Clear(); }
+    IMGUI_API void                  Clear();
+    IMGUI_API void                  BuildLookupTable();
+    IMGUI_API const Glyph*          FindGlyph(unsigned short c) const;
+    IMGUI_API bool                  IsLoaded() const        { return ContainerAtlas != NULL; }
+
+    // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
+    // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.
+    IMGUI_API ImVec2                CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8
+    IMGUI_API ImVec2                CalcTextSizeW(float size, float max_width, const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL) const;                 // wchar
+    IMGUI_API void                  RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, ImDrawVert*& out_vertices, float wrap_width = 0.0f) const;
+    IMGUI_API const char*           CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const;
 };
 
 //---- Include imgui_user.h at the end of imgui.h

+ 547 - 0
3rdparty/stb/stb_rect_pack.h

@@ -0,0 +1,547 @@
+// stb_rect_pack.h - v0.05 - public domain - rectangle packing
+// Sean Barrett 2014
+//
+// Useful for e.g. packing rectangular textures into an atlas.
+// Does not do rotation.
+//
+// Not necessarily the awesomest packing method, but better than
+// the totally naive one in stb_truetype (which is primarily what
+// this is meant to replace).
+//
+// Has only had a few tests run, may have issues.
+//
+// More docs to come.
+//
+// No memory allocations; uses qsort() and assert() from stdlib.
+//
+// This library currently uses the Skyline Bottom-Left algorithm.
+//
+// Please note: better rectangle packers are welcome! Please
+// implement them to the same API, but with a different init
+// function.
+//
+// Version history:
+//
+//     0.05:  added STBRP_ASSERT to allow replacing assert
+//     0.04:  fixed minor bug in STBRP_LARGE_RECTS support
+//     0.01:  initial release
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//       INCLUDE SECTION
+//
+
+#ifndef STB_INCLUDE_STB_RECT_PACK_H
+#define STB_INCLUDE_STB_RECT_PACK_H
+
+#define STB_RECT_PACK_VERSION  1
+
+#ifdef STBRP_STATIC
+#define STBRP_DEF static
+#else
+#define STBRP_DEF extern
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct stbrp_context stbrp_context;
+typedef struct stbrp_node    stbrp_node;
+typedef struct stbrp_rect    stbrp_rect;
+
+#ifdef STBRP_LARGE_RECTS
+typedef int            stbrp_coord;
+#else
+typedef unsigned short stbrp_coord;
+#endif
+
+STBRP_DEF void stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
+// Assign packed locations to rectangles. The rectangles are of type
+// 'stbrp_rect' defined below, stored in the array 'rects', and there
+// are 'num_rects' many of them.
+//
+// Rectangles which are successfully packed have the 'was_packed' flag
+// set to a non-zero value and 'x' and 'y' store the minimum location
+// on each axis (i.e. bottom-left in cartesian coordinates, top-left
+// if you imagine y increasing downwards). Rectangles which do not fit
+// have the 'was_packed' flag set to 0.
+//
+// You should not try to access the 'rects' array from another thread
+// while this function is running, as the function temporarily reorders
+// the array while it executes.
+//
+// To pack into another rectangle, you need to call stbrp_init_target
+// again. To continue packing into the same rectangle, you can call
+// this function again. Calling this multiple times with multiple rect
+// arrays will probably produce worse packing results than calling it
+// a single time with the full rectangle array, but the option is
+// available.
+
+struct stbrp_rect
+{
+   // reserved for your use:
+   int            id;
+
+   // input:
+   stbrp_coord    w, h;
+
+   // output:
+   stbrp_coord    x, y;
+   int            was_packed;  // non-zero if valid packing
+
+}; // 16 bytes, nominally
+
+
+STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
+// Initialize a rectangle packer to:
+//    pack a rectangle that is 'width' by 'height' in dimensions
+//    using temporary storage provided by the array 'nodes', which is 'num_nodes' long
+//
+// You must call this function every time you start packing into a new target.
+//
+// There is no "shutdown" function. The 'nodes' memory must stay valid for
+// the following stbrp_pack_rects() call (or calls), but can be freed after
+// the call (or calls) finish.
+//
+// Note: to guarantee best results, either:
+//       1. make sure 'num_nodes' >= 'width'
+//   or  2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
+//
+// If you don't do either of the above things, widths will be quantized to multiples
+// of small integers to guarantee the algorithm doesn't run out of temporary storage.
+//
+// If you do #2, then the non-quantized algorithm will be used, but the algorithm
+// may run out of temporary storage and be unable to pack some rectangles.
+
+STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
+// Optionally call this function after init but before doing any packing to
+// change the handling of the out-of-temp-memory scenario, described above.
+// If you call init again, this will be reset to the default (false).
+
+
+STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
+// Optionally select which packing heuristic the library should use. Different
+// heuristics will produce better/worse results for different data sets.
+// If you call init again, this will be reset to the default.
+
+enum
+{
+   STBRP_HEURISTIC_Skyline_default=0,
+   STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
+   STBRP_HEURISTIC_Skyline_BF_sortHeight
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// the details of the following structures don't matter to you, but they must
+// be visible so you can handle the memory allocations for them
+
+struct stbrp_node
+{
+   stbrp_coord  x,y;
+   stbrp_node  *next;
+};
+
+struct stbrp_context
+{
+   int width;
+   int height;
+   int align;
+   int init_mode;
+   int heuristic;
+   int num_nodes;
+   stbrp_node *active_head;
+   stbrp_node *free_head;
+   stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//     IMPLEMENTATION SECTION
+//
+
+#ifdef STB_RECT_PACK_IMPLEMENTATION
+#include <stdlib.h>
+
+#ifndef STBRP_ASSERT
+#include <assert.h>
+#define STBRP_ASSERT assert
+#endif
+
+enum
+{
+   STBRP__INIT_skyline = 1
+};
+
+STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
+{
+   switch (context->init_mode) {
+      case STBRP__INIT_skyline:
+         STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
+         context->heuristic = heuristic;
+         break;
+      default:
+         STBRP_ASSERT(0);
+   }
+}
+
+STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
+{
+   if (allow_out_of_mem)
+      // if it's ok to run out of memory, then don't bother aligning them;
+      // this gives better packing, but may fail due to OOM (even though
+      // the rectangles easily fit). @TODO a smarter approach would be to only
+      // quantize once we've hit OOM, then we could get rid of this parameter.
+      context->align = 1;
+   else {
+      // if it's not ok to run out of memory, then quantize the widths
+      // so that num_nodes is always enough nodes.
+      //
+      // I.e. num_nodes * align >= width
+      //                  align >= width / num_nodes
+      //                  align = ceil(width/num_nodes)
+
+      context->align = (context->width + context->num_nodes-1) / context->num_nodes;
+   }
+}
+
+STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
+{
+   int i;
+#ifndef STBRP_LARGE_RECTS
+   STBRP_ASSERT(width <= 0xffff && height <= 0xffff);
+#endif
+
+   for (i=0; i < num_nodes-1; ++i)
+      nodes[i].next = &nodes[i+1];
+   nodes[i].next = NULL;
+   context->init_mode = STBRP__INIT_skyline;
+   context->heuristic = STBRP_HEURISTIC_Skyline_default;
+   context->free_head = &nodes[0];
+   context->active_head = &context->extra[0];
+   context->width = width;
+   context->height = height;
+   context->num_nodes = num_nodes;
+   stbrp_setup_allow_out_of_mem(context, 0);
+
+   // node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
+   context->extra[0].x = 0;
+   context->extra[0].y = 0;
+   context->extra[0].next = &context->extra[1];
+   context->extra[1].x = (stbrp_coord) width;
+#ifdef STBRP_LARGE_RECTS
+   context->extra[1].y = (1<<30);
+#else
+   context->extra[1].y = 65535;
+#endif
+   context->extra[1].next = NULL;
+}
+
+// find minimum y position if it starts at x1
+static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
+{
+   (void)c;
+   stbrp_node *node = first;
+   int x1 = x0 + width;
+   int min_y, visited_width, waste_area;
+   STBRP_ASSERT(first->x <= x0);
+
+   #if 0
+   // skip in case we're past the node
+   while (node->next->x <= x0)
+      ++node;
+   #else
+   STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
+   #endif
+
+   STBRP_ASSERT(node->x <= x0);
+
+   min_y = 0;
+   waste_area = 0;
+   visited_width = 0;
+   while (node->x < x1) {
+      if (node->y > min_y) {
+         // raise min_y higher.
+         // we've accounted for all waste up to min_y,
+         // but we'll now add more waste for everything we've visted
+         waste_area += visited_width * (node->y - min_y);
+         min_y = node->y;
+         // the first time through, visited_width might be reduced
+         if (node->x < x0)
+            visited_width += node->next->x - x0;
+         else
+            visited_width += node->next->x - node->x;
+      } else {
+         // add waste area
+         int under_width = node->next->x - node->x;
+         if (under_width + visited_width > width)
+            under_width = width - visited_width;
+         waste_area += under_width * (min_y - node->y);
+         visited_width += under_width;
+      }
+      node = node->next;
+   }
+
+   *pwaste = waste_area;
+   return min_y;
+}
+
+typedef struct
+{
+   int x,y;
+   stbrp_node **prev_link;
+} stbrp__findresult;
+
+static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
+{
+   int best_waste = (1<<30), best_x, best_y = (1 << 30);
+   stbrp__findresult fr;
+   stbrp_node **prev, *node, *tail, **best = NULL;
+
+   // align to multiple of c->align
+   width = (width + c->align - 1);
+   width -= width % c->align;
+   STBRP_ASSERT(width % c->align == 0);
+
+   node = c->active_head;
+   prev = &c->active_head;
+   while (node->x + width <= c->width) {
+      int y,waste;
+      y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
+      if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
+         // bottom left
+         if (y < best_y) {
+            best_y = y;
+            best = prev;
+         }
+      } else {
+         // best-fit
+         if (y + height <= c->height) {
+            // can only use it if it first vertically
+            if (y < best_y || (y == best_y && waste < best_waste)) {
+               best_y = y;
+               best_waste = waste;
+               best = prev;
+            }
+         }
+      }
+      prev = &node->next;
+      node = node->next;
+   }
+
+   best_x = (best == NULL) ? 0 : (*best)->x;
+
+   // if doing best-fit (BF), we also have to try aligning right edge to each node position
+   //
+   // e.g, if fitting
+   //
+   //     ____________________
+   //    |____________________|
+   //
+   //            into
+   //
+   //   |                         |
+   //   |             ____________|
+   //   |____________|
+   //
+   // then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
+   //
+   // This makes BF take about 2x the time
+
+   if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
+      tail = c->active_head;
+      node = c->active_head;
+      prev = &c->active_head;
+      // find first node that's admissible
+      while (tail->x < width)
+         tail = tail->next;
+      while (tail) {
+         int xpos = tail->x - width;
+         int y,waste;
+         STBRP_ASSERT(xpos >= 0);
+         // find the left position that matches this
+         while (node->next->x <= xpos) {
+            prev = &node->next;
+            node = node->next;
+         }
+         STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
+         y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
+         if (y + height < c->height) {
+            if (y <= best_y) {
+               if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
+                  best_x = xpos;
+                  STBRP_ASSERT(y <= best_y);
+                  best_y = y;
+                  best_waste = waste;
+                  best = prev;
+               }
+            }
+         }
+         tail = tail->next;
+      }         
+   }
+
+   fr.prev_link = best;
+   fr.x = best_x;
+   fr.y = best_y;
+   return fr;
+}
+
+static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
+{
+   // find best position according to heuristic
+   stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
+   stbrp_node *node, *cur;
+
+   // bail if:
+   //    1. it failed
+   //    2. the best node doesn't fit (we don't always check this)
+   //    3. we're out of memory
+   if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
+      res.prev_link = NULL;
+      return res;
+   }
+
+   // on success, create new node
+   node = context->free_head;
+   node->x = (stbrp_coord) res.x;
+   node->y = (stbrp_coord) (res.y + height);
+
+   context->free_head = node->next;
+
+   // insert the new node into the right starting point, and
+   // let 'cur' point to the remaining nodes needing to be
+   // stiched back in
+
+   cur = *res.prev_link;
+   if (cur->x < res.x) {
+      // preserve the existing one, so start testing with the next one
+      stbrp_node *next = cur->next;
+      cur->next = node;
+      cur = next;
+   } else {
+      *res.prev_link = node;
+   }
+
+   // from here, traverse cur and free the nodes, until we get to one
+   // that shouldn't be freed
+   while (cur->next && cur->next->x <= res.x + width) {
+      stbrp_node *next = cur->next;
+      // move the current node to the free list
+      cur->next = context->free_head;
+      context->free_head = cur;
+      cur = next;
+   }
+
+   // stitch the list back in
+   node->next = cur;
+
+   if (cur->x < res.x + width)
+      cur->x = (stbrp_coord) (res.x + width);
+
+#ifdef _DEBUG
+   cur = context->active_head;
+   while (cur->x < context->width) {
+      STBRP_ASSERT(cur->x < cur->next->x);
+      cur = cur->next;
+   }
+   STBRP_ASSERT(cur->next == NULL);
+
+   {
+      stbrp_node *L1 = NULL, *L2 = NULL;
+      int count=0;
+      cur = context->active_head;
+      while (cur) {
+         L1 = cur;
+         cur = cur->next;
+         ++count;
+      }
+      cur = context->free_head;
+      while (cur) {
+         L2 = cur;
+         cur = cur->next;
+         ++count;
+      }
+      STBRP_ASSERT(count == context->num_nodes+2);
+   }
+#endif
+
+   return res;
+}
+
+static int rect_height_compare(const void *a, const void *b)
+{
+   stbrp_rect *p = (stbrp_rect *) a;
+   stbrp_rect *q = (stbrp_rect *) b;
+   if (p->h > q->h)
+      return -1;
+   if (p->h < q->h)
+      return  1;
+   return (p->w > q->w) ? -1 : (p->w < q->w);
+}
+
+static int rect_width_compare(const void *a, const void *b)
+{
+   stbrp_rect *p = (stbrp_rect *) a;
+   stbrp_rect *q = (stbrp_rect *) b;
+   if (p->w > q->w)
+      return -1;
+   if (p->w < q->w)
+      return  1;
+   return (p->h > q->h) ? -1 : (p->h < q->h);
+}
+
+static int rect_original_order(const void *a, const void *b)
+{
+   stbrp_rect *p = (stbrp_rect *) a;
+   stbrp_rect *q = (stbrp_rect *) b;
+   return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
+}
+
+#ifdef STBRP_LARGE_RECTS
+#define STBRP__MAXVAL  0xffffffff
+#else
+#define STBRP__MAXVAL  0xffff
+#endif
+
+STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
+{
+   int i;
+
+   // we use the 'was_packed' field internally to allow sorting/unsorting
+   for (i=0; i < num_rects; ++i) {
+      rects[i].was_packed = i;
+      #ifndef STBRP_LARGE_RECTS
+      STBRP_ASSERT(rects[i].w <= 0xffff && rects[i].h <= 0xffff);
+      #endif
+   }
+
+   // sort according to heuristic
+   qsort(rects, num_rects, sizeof(rects[0]), rect_height_compare);
+
+   for (i=0; i < num_rects; ++i) {
+      stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
+      if (fr.prev_link) {
+         rects[i].x = (stbrp_coord) fr.x;
+         rects[i].y = (stbrp_coord) fr.y;
+      } else {
+         rects[i].x = rects[i].y = STBRP__MAXVAL;
+      }
+   }
+
+   // unsort
+   qsort(rects, num_rects, sizeof(rects[0]), rect_original_order);
+
+   // set was_packed flags
+   for (i=0; i < num_rects; ++i)
+      rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
+}
+#endif

File diff suppressed because it is too large
+ 672 - 95
3rdparty/stb/stb_truetype.h


+ 4 - 2
examples/09-hdr/hdr.cpp

@@ -216,8 +216,10 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 	bgfx::FrameBufferHandle blur;
 	blur = bgfx::createFrameBuffer(width/8, height/8, bgfx::TextureFormat::BGRA8);
 
-	void* data = load("font/droidsans.ttf");
-	imguiCreate(data);
+	// Imgui.
+	uint32_t size;
+	void* data = load("font/droidsans.ttf", &size);
+	imguiCreate(data, size);
 	free(data);
 
 	const bgfx::RendererType::Enum renderer = bgfx::getRendererType();

+ 7 - 11
examples/11-fontsdf/fontsdf.cpp

@@ -4,6 +4,7 @@
  */
 
 #include "common.h"
+#include "bgfx_utils.h"
 
 #include <bgfx.h>
 #include <bx/timer.h>
@@ -85,15 +86,10 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 		, 0
 		);
 
-	FILE* file = fopen("font/droidsans.ttf", "rb");
-	uint32_t size = (uint32_t)fsize(file);
-	void* data = malloc(size);
-	size_t ignore = fread(data, 1, size, file);
-	BX_UNUSED(ignore);
-	fclose(file);
-
-	imguiCreate(data);
-
+	// Imgui.
+	uint32_t size;
+	void* data = load("font/droidsans.ttf", &size);
+	imguiCreate(data, size);
 	free(data);
 
 	char* bigText = loadText( "text/sherlock_holmes_a_scandal_in_bohemia_arthur_conan_doyle.txt");
@@ -170,9 +166,9 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 		if (recomputeVisibleText)
 		{
 			textBufferManager->clearTextBuffer(scrollableBuffer);
-			metrics.getSubText(bigText,(uint32_t)textScroll, (uint32_t)(textScroll+visibleLineCount), textBegin, textEnd);			
+			metrics.getSubText(bigText,(uint32_t)textScroll, (uint32_t)(textScroll+visibleLineCount), textBegin, textEnd);
 			textBufferManager->appendText(scrollableBuffer, fontScaled, textBegin, textEnd);
-		}			
+		}
 
 		imguiEndScrollArea();
 

+ 17 - 16
examples/12-lod/lod.cpp

@@ -43,15 +43,15 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 		, 1.0f
 		, 0
 		);
-	
+
 	bgfx::UniformHandle u_texColor   = bgfx::createUniform("u_texColor",   bgfx::UniformType::Uniform1iv);
 	bgfx::UniformHandle u_stipple    = bgfx::createUniform("u_stipple",    bgfx::UniformType::Uniform3fv);
 	bgfx::UniformHandle u_texStipple = bgfx::createUniform("u_texStipple", bgfx::UniformType::Uniform1iv);
 
 	bgfx::ProgramHandle program = loadProgram("vs_tree", "fs_tree");
 
-	bgfx::TextureHandle textureLeafs = loadTexture("leafs1.dds"); 
-	bgfx::TextureHandle textureBark  = loadTexture("bark1.dds"); 
+	bgfx::TextureHandle textureLeafs = loadTexture("leafs1.dds");
+	bgfx::TextureHandle textureBark  = loadTexture("bark1.dds");
 
 	bgfx::TextureHandle textureStipple;
 
@@ -62,7 +62,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 	{
 		stipple->data[knightTour[ii].m_y * 8 + knightTour[ii].m_x] = ii*4;
 	}
-		
+
 	textureStipple = bgfx::createTexture2D(8, 4, 1, bgfx::TextureFormat::R8, BGFX_TEXTURE_MAG_POINT|BGFX_TEXTURE_MIN_POINT, stipple);
 
 	Mesh* meshTop[3] =
@@ -71,7 +71,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 		meshLoad("meshes/tree1b_lod1_1.bin"),
 		meshLoad("meshes/tree1b_lod2_1.bin"),
 	};
-	
+
 	Mesh* meshTrunk[3] =
 	{
 		meshLoad("meshes/tree1b_lod0_2.bin"),
@@ -80,8 +80,9 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 	};
 
 	// Imgui.
-	void* data = load("font/droidsans.ttf");
-	imguiCreate(data);
+	uint32_t size;
+	void* data = load("font/droidsans.ttf", &size);
+	imguiCreate(data, size);
 	free(data);
 
 	const uint64_t stateCommon = 0
@@ -191,18 +192,18 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 		}
 
 		float mtx[16];
-		bx::mtxScale(mtx, 0.1f, 0.1f, 0.1f); 
+		bx::mtxScale(mtx, 0.1f, 0.1f, 0.1f);
 
 		float stipple[3];
 		float stippleInv[3];
 
 		const int currentLODframe = transitions ? 32-transitionFrame : 32;
 		const int mainLOD = transitions ? currLOD : targetLOD;
-		
+
 		stipple[0] = 0.0f;
 		stipple[1] = -1.0f;
 		stipple[2] = (float(currentLODframe)*4.0f/255.0f) - (1.0f/255.0f);
-	
+
 		stippleInv[0] = (float(31)*4.0f/255.0f);
 		stippleInv[1] = 1.0f;
 		stippleInv[2] = (float(transitionFrame)*4.0f/255.0f) - (1.0f/255.0f);
@@ -217,7 +218,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 		bgfx::setUniform(u_stipple, stipple);
 		meshSubmit(meshTop[mainLOD], 0, program, mtx, stateTransparent);
 
-		if (transitions 
+		if (transitions
 		&& (transitionFrame != 0) )
 		{
 			bgfx::setTexture(0, u_texColor, textureBark);
@@ -230,7 +231,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 			bgfx::setUniform(u_stipple, stippleInv);
 			meshSubmit(meshTop[targetLOD], 0, program, mtx, stateTransparent);
 		}
-	
+
 		int lod = 0;
 		if (eye[2] < -2.5f)
 		{
@@ -249,7 +250,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 				targetLOD = lod;
 			}
 		}
-		
+
 		if (currLOD != targetLOD)
 		{
 			transitionFrame++;
@@ -261,7 +262,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 			transitionFrame = 0;
 		}
 
-		// Advance to next frame. Rendering thread will be kicked to 
+		// Advance to next frame. Rendering thread will be kicked to
 		// process submitted rendering primitives.
 		bgfx::frame();
 	}
@@ -283,8 +284,8 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 
 	bgfx::destroyTexture(textureStipple);
 	bgfx::destroyTexture(textureLeafs);
-	bgfx::destroyTexture(textureBark); 
-	
+	bgfx::destroyTexture(textureBark);
+
 	// Shutdown bgfx.
 	bgfx::shutdown();
 

+ 8 - 83
examples/13-stencil/stencil.cpp

@@ -7,6 +7,7 @@
 #include <vector>
 
 #include "common.h"
+#include "bgfx_utils.h"
 
 #include <bgfx.h>
 #include <bx/timer.h>
@@ -156,70 +157,6 @@ inline void mtxProj(float* _result, float _fovy, float _aspect, float _near, flo
 	bx::mtxProj(_result, _fovy, _aspect, _near, _far, s_flipV);
 }
 
-static void shaderFilePath(char* _out, const char* _name)
-{
-	strcpy(_out, s_shaderPath);
-	strcat(_out, _name);
-	strcat(_out, ".bin");
-}
-
-long int fsize(FILE* _file)
-{
-	long int pos = ftell(_file);
-	fseek(_file, 0L, SEEK_END);
-	long int size = ftell(_file);
-	fseek(_file, pos, SEEK_SET);
-	return size;
-}
-
-static const bgfx::Memory* load(const char* _filePath)
-{
-	FILE* file = fopen(_filePath, "rb");
-	if (NULL != file)
-	{
-		uint32_t size = (uint32_t)fsize(file);
-		const bgfx::Memory* mem = bgfx::alloc(size+1);
-		size_t ignore = fread(mem->data, 1, size, file);
-		BX_UNUSED(ignore);
-		fclose(file);
-		mem->data[mem->size-1] = '\0';
-		return mem;
-	}
-
-	return NULL;
-}
-
-static const bgfx::Memory* loadShader(const char* _name)
-{
-	char filePath[512];
-	shaderFilePath(filePath, _name);
-	return load(filePath);
-}
-
-static const bgfx::Memory* loadTexture(const char* _name)
-{
-	char filePath[512];
-	strcpy(filePath, "textures/");
-	strcat(filePath, _name);
-	return load(filePath);
-}
-
-static bgfx::ProgramHandle loadProgram(const char* _vsName, const char* _fsName)
-{
-	const bgfx::Memory* mem;
-
-	// Load vertex shader.
-	mem = loadShader(_vsName);
-	bgfx::ShaderHandle vsh = bgfx::createShader(mem);
-
-	// Load fragment shader.
-	mem = loadShader(_fsName);
-	bgfx::ShaderHandle fsh = bgfx::createShader(mem);
-
-	// Create program from shaders.
-	return bgfx::createProgram(vsh, fsh, true /* destroy shaders when program is destroyed */);
-}
-
 void setViewClearMask(uint32_t _viewMask, uint8_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil)
 {
 	for (uint32_t view = 0, viewMask = _viewMask, ntz = bx::uint32_cnttz(_viewMask); 0 != viewMask; viewMask >>= 1, view += 1, ntz = bx::uint32_cnttz(viewMask) )
@@ -940,15 +877,10 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 		break;
 	}
 
-	FILE* file = fopen("font/droidsans.ttf", "rb");
-	uint32_t size = (uint32_t)fsize(file);
-	void* data = malloc(size);
-	size_t ignore = fread(data, 1, size, file);
-	BX_UNUSED(ignore);
-	fclose(file);
-
-	imguiCreate(data);
-
+	// Imgui.
+	uint32_t size;
+	void* data = load("font/droidsans.ttf", &size);
+	imguiCreate(data, size);
 	free(data);
 
 	PosNormalTexcoordVertex::init();
@@ -975,16 +907,9 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 	hplaneMesh.load(s_hplaneVertices, BX_COUNTOF(s_hplaneVertices), PosNormalTexcoordVertex::ms_decl, s_planeIndices, BX_COUNTOF(s_planeIndices) );
 	vplaneMesh.load(s_vplaneVertices, BX_COUNTOF(s_vplaneVertices), PosNormalTexcoordVertex::ms_decl, s_planeIndices, BX_COUNTOF(s_planeIndices) );
 
-	const bgfx::Memory* mem;
-
-	mem = loadTexture("figure-rgba.dds");
-	bgfx::TextureHandle figureTex = bgfx::createTexture(mem);
-
-	mem = loadTexture("flare.dds");
-	bgfx::TextureHandle flareTex = bgfx::createTexture(mem);
-
-	mem = loadTexture("fieldstone-rgba.dds");
-	bgfx::TextureHandle fieldstoneTex = bgfx::createTexture(mem);
+	bgfx::TextureHandle figureTex     = loadTexture("figure-rgba.dds");
+	bgfx::TextureHandle flareTex      = loadTexture("flare.dds");
+	bgfx::TextureHandle fieldstoneTex = loadTexture("fieldstone-rgba.dds");
 
 	// Setup lights.
 	const float rgbInnerR[][4] =

+ 7 - 83
examples/14-shadowvolumes/shadowvolumes.cpp

@@ -17,6 +17,7 @@ namespace std { namespace tr1 {} }
 using namespace std::tr1;
 
 #include "common.h"
+#include "bgfx_utils.h"
 
 #include <bgfx.h>
 #include <bx/timer.h>
@@ -120,70 +121,6 @@ static bgfx::UniformHandle u_texColor;
 static bgfx::UniformHandle u_texStencil;
 static bgfx::FrameBufferHandle s_stencilFb;
 
-static void shaderFilePath(char* _out, const char* _name)
-{
-	strcpy(_out, s_shaderPath);
-	strcat(_out, _name);
-	strcat(_out, ".bin");
-}
-
-long int fsize(FILE* _file)
-{
-	long int pos = ftell(_file);
-	fseek(_file, 0L, SEEK_END);
-	long int size = ftell(_file);
-	fseek(_file, pos, SEEK_SET);
-	return size;
-}
-
-static const bgfx::Memory* load(const char* _filePath)
-{
-	FILE* file = fopen(_filePath, "rb");
-	if (NULL != file)
-	{
-		uint32_t size = (uint32_t)fsize(file);
-		const bgfx::Memory* mem = bgfx::alloc(size+1);
-		size_t ignore = fread(mem->data, 1, size, file);
-		BX_UNUSED(ignore);
-		fclose(file);
-		mem->data[mem->size-1] = '\0';
-		return mem;
-	}
-
-	return NULL;
-}
-
-static const bgfx::Memory* loadShader(const char* _name)
-{
-	char filePath[512];
-	shaderFilePath(filePath, _name);
-	return load(filePath);
-}
-
-static const bgfx::Memory* loadTexture(const char* _name)
-{
-	char filePath[512];
-	strcpy(filePath, "textures/");
-	strcat(filePath, _name);
-	return load(filePath);
-}
-
-static bgfx::ProgramHandle loadProgram(const char* _vsName, const char* _fsName)
-{
-	const bgfx::Memory* mem;
-
-	// Load vertex shader.
-	mem = loadShader(_vsName);
-	bgfx::ShaderHandle vsh = bgfx::createShader(mem);
-
-	// Load fragment shader.
-	mem = loadShader(_fsName);
-	bgfx::ShaderHandle fsh = bgfx::createShader(mem);
-
-	// Create program from shaders.
-	return bgfx::createProgram(vsh, fsh, true /* destroy shaders when program is destroyed */);
-}
-
 void setViewClearMask(uint32_t _viewMask, uint8_t _flags, uint32_t _rgba, float _depth, uint8_t _stencil)
 {
 	for (uint32_t view = 0, viewMask = _viewMask, ntz = bx::uint32_cnttz(_viewMask); 0 != viewMask; viewMask >>= 1, view += 1, ntz = bx::uint32_cnttz(viewMask) )
@@ -1957,15 +1894,9 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 	}
 
 	// Imgui
-	FILE* file = fopen("font/droidsans.ttf", "rb");
-	uint32_t size = (uint32_t)fsize(file);
-	void* data = malloc(size);
-	size_t ignore = fread(data, 1, size, file);
-	BX_UNUSED(ignore);
-	fclose(file);
-
-	imguiCreate(data);
-
+	uint32_t size;
+	void* data = load("font/droidsans.ttf", &size);
+	imguiCreate(data, size);
 	free(data);
 
 	PosNormalTexcoordVertex::init();
@@ -1973,16 +1904,9 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 	s_uniforms.init();
 	s_uniforms.submitConstUniforms();
 
-	const bgfx::Memory* mem;
-
-	mem = loadTexture("figure-rgba.dds");
-	bgfx::TextureHandle figureTex = bgfx::createTexture(mem);
-
-	mem = loadTexture("flare.dds");
-	bgfx::TextureHandle flareTex = bgfx::createTexture(mem);
-
-	mem = loadTexture("fieldstone-rgba.dds");
-	bgfx::TextureHandle fieldstoneTex = bgfx::createTexture(mem);
+	bgfx::TextureHandle figureTex     = loadTexture("figure-rgba.dds");
+	bgfx::TextureHandle flareTex      = loadTexture("flare.dds");
+	bgfx::TextureHandle fieldstoneTex = loadTexture("fieldstone-rgba.dds");
 
 	bgfx::TextureHandle fbtextures[] =
 	{

+ 7 - 83
examples/16-shadowmaps/shadowmaps.cpp

@@ -8,6 +8,7 @@
 #include <algorithm>
 
 #include "common.h"
+#include "bgfx_utils.h"
 
 #include <bgfx.h>
 #include <bx/timer.h>
@@ -228,70 +229,6 @@ static bgfx::UniformHandle u_shadowMap[ShadowMapRenderTargets::Count];
 static bgfx::FrameBufferHandle s_rtShadowMap[ShadowMapRenderTargets::Count];
 static bgfx::FrameBufferHandle s_rtBlur;
 
-static void shaderFilePath(char* _out, const char* _name)
-{
-	strcpy(_out, s_shaderPath);
-	strcat(_out, _name);
-	strcat(_out, ".bin");
-}
-
-long int fsize(FILE* _file)
-{
-	long int pos = ftell(_file);
-	fseek(_file, 0L, SEEK_END);
-	long int size = ftell(_file);
-	fseek(_file, pos, SEEK_SET);
-	return size;
-}
-
-static const bgfx::Memory* load(const char* _filePath)
-{
-	FILE* file = fopen(_filePath, "rb");
-	if (NULL != file)
-	{
-		uint32_t size = (uint32_t)fsize(file);
-		const bgfx::Memory* mem = bgfx::alloc(size+1);
-		size_t ignore = fread(mem->data, 1, size, file);
-		BX_UNUSED(ignore);
-		fclose(file);
-		mem->data[mem->size-1] = '\0';
-		return mem;
-	}
-
-	return NULL;
-}
-
-static const bgfx::Memory* loadShader(const char* _name)
-{
-	char filePath[512];
-	shaderFilePath(filePath, _name);
-	return load(filePath);
-}
-
-static const bgfx::Memory* loadTexture(const char* _name)
-{
-	char filePath[512];
-	strcpy(filePath, "textures/");
-	strcat(filePath, _name);
-	return load(filePath);
-}
-
-static bgfx::ProgramHandle loadProgram(const char* _vsName, const char* _fsName)
-{
-	const bgfx::Memory* mem;
-
-	// Load vertex shader.
-	mem = loadShader(_vsName);
-	bgfx::ShaderHandle vsh = bgfx::createShader(mem);
-
-	// Load fragment shader.
-	mem = loadShader(_fsName);
-	bgfx::ShaderHandle fsh = bgfx::createShader(mem);
-
-	// Create program from shaders.
-	return bgfx::createProgram(vsh, fsh, true /* destroy shaders when program is destroyed */);
-}
-
 void mtxBillboard(float* __restrict _result
 				  , const float* __restrict _view
 				  , const float* __restrict _pos
@@ -1418,15 +1355,9 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 	}
 
 	// Imgui.
-	FILE* file = fopen("font/droidsans.ttf", "rb");
-	uint32_t size = (uint32_t)fsize(file);
-	void* data = malloc(size);
-	size_t ignore = fread(data, 1, size, file);
-	BX_UNUSED(ignore);
-	fclose(file);
-
-	imguiCreate(data);
-
+	uint32_t size;
+	void* data = load("font/droidsans.ttf", &size);
+	imguiCreate(data, size);
 	free(data);
 
 	// Uniforms.
@@ -1456,16 +1387,9 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 	PosColorTexCoord0Vertex::init();
 
 	// Textures.
-	const bgfx::Memory* mem;
-
-	mem = loadTexture("figure-rgba.dds");
-	bgfx::TextureHandle texFigure = bgfx::createTexture(mem);
-
-	mem = loadTexture("flare.dds");
-	bgfx::TextureHandle texFlare = bgfx::createTexture(mem);
-
-	mem = loadTexture("fieldstone-rgba.dds");
-	bgfx::TextureHandle texFieldstone = bgfx::createTexture(mem);
+	bgfx::TextureHandle texFigure     = loadTexture("figure-rgba.dds");
+	bgfx::TextureHandle texFlare      = loadTexture("flare.dds");
+	bgfx::TextureHandle texFieldstone = loadTexture("fieldstone-rgba.dds");
 
 	// Meshes.
 	Mesh bunnyMesh;

+ 3 - 3
examples/17-drawstress/drawstress.cpp

@@ -11,7 +11,7 @@
 
 // embedded shaders
 #include "vs_drawstress.bin.h"
-#include "fs_drawstress.bin.h" 
+#include "fs_drawstress.bin.h"
 
 // embedded font
 #include "droidsans.ttf.h"
@@ -238,7 +238,7 @@ BX_NO_INLINE bool mainloop()
 			}
 		}
 
-		// Advance to next frame. Rendering thread will be kicked to 
+		// Advance to next frame. Rendering thread will be kicked to
 		// process submitted rendering primitives.
 		bgfx::frame();
 
@@ -310,7 +310,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 	mem = bgfx::makeRef(s_cubeIndices, sizeof(s_cubeIndices) );
 	ibh = bgfx::createIndexBuffer(mem);
 
-	imguiCreate(s_droidSansTtf);
+	imguiCreate(s_droidSansTtf, sizeof(s_droidSansTtf) );
 
 #if BX_PLATFORM_EMSCRIPTEN
 	emscripten_set_main_loop(&loop, -1, 1);

+ 3 - 2
examples/18-ibl/ibl.cpp

@@ -240,8 +240,9 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 		);
 
 	// Imgui.
-	void* data = load("font/droidsans.ttf");
-	imguiCreate(data);
+	uint32_t size;
+	void* data = load("font/droidsans.ttf", &size);
+	imguiCreate(data, size);
 	free(data);
 
 	// Uniforms.

+ 7 - 6
examples/19-oit/oit.cpp

@@ -166,7 +166,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 	// Get renderer capabilities info.
 	const bgfx::Caps* caps = bgfx::getCaps();
 
-	// Setup root path for binary shaders. Shader binaries are different 
+	// Setup root path for binary shaders. Shader binaries are different
 	// for each renderer.
 	switch (caps->rendererType)
 	{
@@ -180,8 +180,9 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 	}
 
 	// Imgui.
-	void* data = load("font/droidsans.ttf");
-	imguiCreate(data);
+	uint32_t size;
+	void* data = load("font/droidsans.ttf", &size);
+	imguiCreate(data, size);
 	free(data);
 
 	const bgfx::Memory* mem;
@@ -206,7 +207,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 	bgfx::ProgramHandle wbBlit         = loadProgram("vs_oit_blit", "fs_oit_wb_blit"          );
 
 	bgfx::TextureHandle fbtextures[2] = { BGFX_INVALID_HANDLE, BGFX_INVALID_HANDLE };
-	bgfx::FrameBufferHandle fbh = BGFX_INVALID_HANDLE; 
+	bgfx::FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
 
 	int64_t timeOffset = bx::getHPCounter();
 
@@ -302,7 +303,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 
 		float at[3] = { 0.0f, 0.0f, 0.0f };
 		float eye[3] = { 0.0f, 0.0f, -7.0f };
-	
+
 		float view[16];
 		float proj[16];
 
@@ -437,7 +438,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 			bgfx::submit(1);
 		}
 
-		// Advance to next frame. Rendering thread will be kicked to 
+		// Advance to next frame. Rendering thread will be kicked to
 		// process submitted rendering primitives.
 		bgfx::frame();
 	}

+ 12 - 10
examples/21-deferred/deferred.cpp

@@ -300,11 +300,13 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 	bgfx::TextureHandle textureNormal = loadTexture("fieldstone-n.dds");
 
 	bgfx::TextureHandle gbufferTex[3] = { BGFX_INVALID_HANDLE, BGFX_INVALID_HANDLE, BGFX_INVALID_HANDLE };
-	bgfx::FrameBufferHandle gbuffer = BGFX_INVALID_HANDLE; 
-	bgfx::FrameBufferHandle lightBuffer = BGFX_INVALID_HANDLE; 
+	bgfx::FrameBufferHandle gbuffer = BGFX_INVALID_HANDLE;
+	bgfx::FrameBufferHandle lightBuffer = BGFX_INVALID_HANDLE;
 
-	void* data = load("font/droidsans.ttf");
-	imguiCreate(data);
+	// Imgui.
+	uint32_t size;
+	void* data = load("font/droidsans.ttf", &size);
+	imguiCreate(data, size);
 	free(data);
 
 	const int64_t timeOffset = bx::getHPCounter();
@@ -434,7 +436,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 			}
 
 			imguiSlider("Lights animation speed", lightAnimationSpeed, 0.0f, 0.4f, 0.01f);
-			
+
 			imguiEndScrollArea();
 			imguiEndFrame();
 
@@ -470,10 +472,10 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 				const float aspectRatio = float(height)/float(width);
 				const float size = 10.0f;
 				bx::mtxOrtho(proj, -size, size, size*aspectRatio, -size*aspectRatio, 0.0f, 1000.0f);
-				bgfx::setViewTransform(RENDER_PASS_DEBUG_GBUFFER_ID, NULL, proj); 
+				bgfx::setViewTransform(RENDER_PASS_DEBUG_GBUFFER_ID, NULL, proj);
 
 				bx::mtxOrtho(proj, 0.0f, (float)width, 0.0f, (float)height, 0.0f, 1000.0f);
-				bgfx::setViewTransform(RENDER_PASS_DEBUG_LIGHTS_ID, NULL, proj); 
+				bgfx::setViewTransform(RENDER_PASS_DEBUG_LIGHTS_ID, NULL, proj);
 			}
 
 			const uint32_t dim = 11;
@@ -539,7 +541,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 				Aabb aabb;
 				sphereToAabb(aabb, lightPosRadius);
 
-				float box[8][3] = 
+				float box[8][3] =
 				{
 					{ aabb.m_min[0], aabb.m_min[1], aabb.m_min[2] },
 					{ aabb.m_min[0], aabb.m_min[1], aabb.m_max[2] },
@@ -633,7 +635,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 
 					uint8_t val = light&7;
 					float lightRgbInnerR[4] =
-					{ 
+					{
 						val & 0x1 ? 1.0f : 0.25f,
 						val & 0x2 ? 1.0f : 0.25f,
 						val & 0x4 ? 1.0f : 0.25f,
@@ -695,7 +697,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 			}
 		}
 
-		// Advance to next frame. Rendering thread will be kicked to 
+		// Advance to next frame. Rendering thread will be kicked to
 		// process submitted rendering primitives.
 		bgfx::frame();
 	}

+ 4 - 2
examples/24-nbody/nbody.cpp

@@ -117,8 +117,10 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 		, 0
 		);
 
-	void* data = load("font/droidsans.ttf");
-	imguiCreate(data);
+	// Imgui.
+	uint32_t size;
+	void* data = load("font/droidsans.ttf", &size);
+	imguiCreate(data, size);
 	free(data);
 
 	bgfx::VertexDecl quadVertexDecl;

+ 11 - 3
examples/common/bgfx_utils.cpp

@@ -18,7 +18,7 @@ namespace stl = tinystl;
 
 #include "bgfx_utils.h"
 
-void* load(bx::FileReaderI* _reader, const char* _filePath)
+void* load(bx::FileReaderI* _reader, const char* _filePath, uint32_t* _size)
 {
 	if (0 == bx::open(_reader, _filePath) )
 	{
@@ -26,15 +26,23 @@ void* load(bx::FileReaderI* _reader, const char* _filePath)
 		void* data = malloc(size);
 		bx::read(_reader, data, size);
 		bx::close(_reader);
+		if (NULL != _size)
+		{
+			*_size = size;
+		}
 		return data;
 	}
 
+	if (NULL != _size)
+	{
+		*_size = 0;
+	}
 	return NULL;
 }
 
-void* load(const char* _filePath)
+void* load(const char* _filePath, uint32_t* _size)
 {
-	return load(entry::getFileReader(), _filePath);
+	return load(entry::getFileReader(), _filePath, _size);
 }
 
 static const bgfx::Memory* loadMem(bx::FileReaderI* _reader, const char* _filePath)

+ 1 - 1
examples/common/bgfx_utils.h

@@ -8,7 +8,7 @@
 
 #include <bgfx.h>
 
-void* load(const char* _filePath);
+void* load(const char* _filePath, uint32_t* _size = NULL);
 bgfx::ShaderHandle loadShader(const char* _name);
 bgfx::ProgramHandle loadProgram(const char* _vsName, const char* _fsName);
 bgfx::TextureHandle loadTexture(const char* _name, uint32_t _flags = BGFX_TEXTURE_NONE, uint8_t _skip = 0, bgfx::TextureInfo* _info = NULL);

+ 4 - 4
examples/common/imgui/imgui.cpp

@@ -440,9 +440,9 @@ struct Imgui
 		return bgfx::createTexture2D(_width, _height, 0, bgfx::TextureFormat::BGRA8, 0, mem);
 	}
 
-	ImguiFontHandle create(const void* _data, float _fontSize)
+	ImguiFontHandle create(const void* _data, uint32_t _size, float _fontSize)
 	{
-		IMGUI_create();
+		IMGUI_create(_data, _size, _fontSize);
 
 		m_nvg = nvgCreate(1, m_view);
 		nvgCreateFontMem(m_nvg, "default", (unsigned char*)_data, INT32_MAX, 0);
@@ -3051,9 +3051,9 @@ struct Imgui
 
 static Imgui s_imgui;
 
-ImguiFontHandle imguiCreate(const void* _data, float _fontSize)
+ImguiFontHandle imguiCreate(const void* _data, uint32_t _size, float _fontSize)
 {
-	return s_imgui.create(_data, _fontSize);
+	return s_imgui.create(_data, _size, _fontSize);
 }
 
 void imguiDestroy()

+ 1 - 1
examples/common/imgui/imgui.h

@@ -121,7 +121,7 @@ ImguiFontHandle imguiCreateFont(const void* _data, float _fontSize=15.0f);
 void imguiSetFont(ImguiFontHandle _handle);
 ImguiFontHandle imguiGetCurrentFont();
 
-ImguiFontHandle imguiCreate(const void* _data, float _fontSize=15.0f);
+ImguiFontHandle imguiCreate(const void* _data, uint32_t _size, float _fontSize = 15.0f);
 void imguiDestroy();
 
 void imguiBeginFrame(int32_t _mx, int32_t _my, uint8_t _button, int32_t _scroll, uint16_t _width, uint16_t _height, char _inputChar = 0, uint8_t _view = 31);

+ 14 - 25
examples/common/imgui/ocornut_imgui.cpp

@@ -79,14 +79,14 @@ struct OcornutImguiContext
 		}
 	}
 
-	void create()
+	void create(const void* _data, uint32_t _size, float _fontSize)
 	{
 		m_viewId = 31;
 
 		ImGuiIO& io = ImGui::GetIO();
 		io.DisplaySize = ImVec2(1280.0f, 720.0f);
 		io.DeltaTime = 1.0f / 60.0f;
-		io.PixelCenterOffset = bgfx::RendererType::Direct3D9 == bgfx::getRendererType() ? -0.5f : 0.0f;
+//		io.PixelCenterOffset = bgfx::RendererType::Direct3D9 == bgfx::getRendererType() ? -0.5f : 0.0f;
 
 		const bgfx::Memory* vsmem;
 		const bgfx::Memory* fsmem;
@@ -122,34 +122,23 @@ struct OcornutImguiContext
 
 		s_tex = bgfx::createUniform("s_tex", bgfx::UniformType::Uniform1i);
 
-		const void* png_data;
-		unsigned int png_size;
-		ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size);
+		uint8_t* data;
+		int32_t width;
+		int32_t height;
+		void* font = malloc(_size);
+		memcpy(font, _data, _size);
+		io.Fonts->AddFontFromMemoryTTF(const_cast<void*>(font), _size, _fontSize);
 
-		int tex_x, tex_y, pitch, tex_comp;
-		void* tex_data = stbi_load_from_memory( (const unsigned char*)png_data
-				, (int)png_size
-				, &tex_x
-				, &tex_y
-				, &tex_comp
-				, 0
-				);
+		io.Fonts->GetTexDataAsRGBA32(&data, &width, &height);
 
-		pitch = tex_x * 4;
-
-		const bgfx::Memory* mem = bgfx::alloc((uint32_t)(tex_y * pitch));
-		memcpy(mem->data, tex_data, size_t(pitch * tex_y));
-
-		m_texture = bgfx::createTexture2D( (uint16_t)tex_x
-			, (uint16_t)tex_y
+		m_texture = bgfx::createTexture2D( (uint16_t)width
+			, (uint16_t)height
 			, 1
 			, bgfx::TextureFormat::BGRA8
 			, BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT
-			, mem
+			, bgfx::copy(data, width*height*4)
 			);
 
-		stbi_image_free(tex_data);
-
 		io.RenderDrawListsFn = imguiRender;
 	}
 
@@ -192,9 +181,9 @@ static void imguiRender(ImDrawList** const _lists, int _count)
 	s_ctx.render(_lists, _count);
 }
 
-void IMGUI_create()
+void IMGUI_create(const void* _data, uint32_t _size, float _fontSize)
 {
-	s_ctx.create();
+	s_ctx.create(_data, _size, _fontSize);
 }
 
 void IMGUI_destroy()

+ 1 - 1
examples/common/imgui/ocornut_imgui.h

@@ -8,7 +8,7 @@
 
 #include <ocornut-imgui/imgui.h>
 
-void IMGUI_create();
+void IMGUI_create(const void* _data, uint32_t _size, float _fontSize);
 void IMGUI_destroy();
 void IMGUI_beginFrame(int32_t _mx, int32_t _my, uint8_t _button, int _width, int _height, char _inputChar, uint8_t _viewId);
 void IMGUI_endFrame();

+ 6 - 5
examples/common/nanovg/fontstash.h

@@ -41,7 +41,7 @@ enum FONSalign {
 enum FONSerrorCode {
 	// Font atlas is full.
 	FONS_ATLAS_FULL = 1,
-	// Scratch memory used to render glyphs is full, requested size reported in 'val', you may need to bump up FONS_SCRATCH_BUF_SIZE.		
+	// Scratch memory used to render glyphs is full, requested size reported in 'val', you may need to bump up FONS_SCRATCH_BUF_SIZE.
 	FONS_SCRATCH_FULL = 2,
 	// Calls to fonsPushState has craeted too large stack, if you need deep state stack bump up FONS_MAX_STATES.
 	FONS_STATES_OVERFLOW = 3,
@@ -90,7 +90,7 @@ void fonsDeleteInternal(FONScontext* s);
 void fonsSetErrorCallback(FONScontext* s, void (*callback)(void* uptr, int error, int val), void* uptr);
 // Returns current atlas size.
 void fonsGetAtlasSize(FONScontext* s, int* width, int* height);
-// Expands the atlas size. 
+// Expands the atlas size.
 int fonsExpandAtlas(FONScontext* s, int width, int height);
 // Reseta the whole stash.
 int fonsResetAtlas(FONScontext* stash, int width, int height);
@@ -154,7 +154,7 @@ typedef struct FONSttFontImpl FONSttFontImpl;
 static FT_Library ftLibrary;
 
 int fons__tt_init(FONScontext *context)
-{ 
+{
 	FT_Error ftError;
         FONS_NOTUSED(context);
 	ftError = FT_Init_FreeType(&ftLibrary);
@@ -249,6 +249,7 @@ static void fons__tmpfree(void* ptr, void* up);
 #	include <string.h>
 #endif // 0
 
+#define STBTT_DEF extern
 #include <stb/stb_truetype.h>
 
 struct FONSttFontImpl {
@@ -1409,7 +1410,7 @@ void fonsDrawDebug(FONScontext* stash, float x, float y)
 }
 
 float fonsTextBounds(FONScontext* stash,
-					 float x, float y, 
+					 float x, float y,
 					 const char* str, const char* end,
 					 float* bounds)
 {
@@ -1597,7 +1598,7 @@ int fonsExpandAtlas(FONScontext* stash, int width, int height)
 	height = fons__maxi(height, stash->params.height);
 
 	if (width == stash->params.width && height == stash->params.height)
-		return 1;	
+		return 1;
 
 	// Flush pending glyphs.
 	fons__flush(stash);

Some files were not shown because too many files changed in this diff