summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty
diff options
context:
space:
mode:
author Branimir Karadžić <branimirkaradzic@gmail.com>2016-04-04 13:52:25 +0200
committer Miodrag Milanovic <mmicko@gmail.com>2016-04-04 13:52:25 +0200
commite63f379a0ef420cf720b7655ea63e19330954eb8 (patch)
tree1c51de36d7fbd9f5218b165b71f3ec9aa1bcfe36 /3rdparty
parent9496a5b24d7fb14dcb38bd16ec8ca528ebdfee1b (diff)
Update BGFX to latest (nw)
Diffstat (limited to '3rdparty')
-rw-r--r--3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp143
-rw-r--r--3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h35
-rw-r--r--3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp13
-rw-r--r--3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h2
-rw-r--r--3rdparty/bgfx/3rdparty/stb/stb_image.c960
-rw-r--r--3rdparty/bgfx/3rdparty/stb/stb_rect_pack.h55
-rw-r--r--3rdparty/bgfx/3rdparty/stb/stb_textedit.h84
-rw-r--r--3rdparty/bgfx/3rdparty/stb/stb_truetype.h159
-rw-r--r--3rdparty/bgfx/CONTRIBUTING.md (renamed from 3rdparty/bgfx/CONTRUBUTING.md)3
-rw-r--r--3rdparty/bgfx/README.md4
-rw-r--r--3rdparty/bgfx/examples/00-helloworld/helloworld.cpp191
-rw-r--r--3rdparty/bgfx/examples/01-cubes/cubes.cpp6
-rw-r--r--3rdparty/bgfx/examples/02-metaballs/metaballs.cpp6
-rw-r--r--3rdparty/bgfx/examples/03-raymarch/raymarch.cpp16
-rw-r--r--3rdparty/bgfx/examples/04-mesh/mesh.cpp6
-rw-r--r--3rdparty/bgfx/examples/05-instancing/instancing.cpp6
-rw-r--r--3rdparty/bgfx/examples/06-bump/bump.cpp6
-rw-r--r--3rdparty/bgfx/examples/09-hdr/hdr.cpp23
-rw-r--r--3rdparty/bgfx/examples/12-lod/lod.cpp6
-rw-r--r--3rdparty/bgfx/examples/14-shadowvolumes/shadowvolumes.cpp19
-rw-r--r--3rdparty/bgfx/examples/21-deferred/deferred.cpp10
-rw-r--r--3rdparty/bgfx/examples/21-deferred/fs_deferred_light.sc2
-rw-r--r--3rdparty/bgfx/examples/24-nbody/nbody.cpp6
-rw-r--r--3rdparty/bgfx/examples/26-occlusion/occlusion.cpp7
-rw-r--r--3rdparty/bgfx/examples/27-terrain/terrain.cpp7
-rw-r--r--3rdparty/bgfx/include/bgfx/bgfx.h5
-rw-r--r--3rdparty/bgfx/include/bgfx/c99/bgfx.h2
-rw-r--r--3rdparty/bgfx/scripts/genie.lua45
-rw-r--r--3rdparty/bgfx/src/amalgamated.cpp4
-rw-r--r--3rdparty/bgfx/src/bgfx.cpp4
-rw-r--r--3rdparty/bgfx/src/bgfx_shader.sh98
-rw-r--r--3rdparty/bgfx/src/debug_renderdoc.cpp (renamed from 3rdparty/bgfx/src/renderdoc.cpp)0
-rw-r--r--3rdparty/bgfx/src/debug_renderdoc.h (renamed from 3rdparty/bgfx/src/renderdoc.h)0
-rw-r--r--3rdparty/bgfx/src/glimports.h2
-rw-r--r--3rdparty/bgfx/src/hmd_ovr.cpp249
-rw-r--r--3rdparty/bgfx/src/hmd_ovr.h (renamed from 3rdparty/bgfx/src/ovr.h)98
-rw-r--r--3rdparty/bgfx/src/ovr.cpp328
-rw-r--r--3rdparty/bgfx/src/renderer_d3d11.cpp273
-rw-r--r--3rdparty/bgfx/src/renderer_d3d11.h4
-rw-r--r--3rdparty/bgfx/src/renderer_gl.cpp254
-rw-r--r--3rdparty/bgfx/src/renderer_gl.h20
41 files changed, 1776 insertions, 1385 deletions
diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp
index 77fe7decfdc..eab90ad5b1d 100644
--- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp
+++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.cpp
@@ -152,6 +152,8 @@
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.
+ - 2016/04/03 (1.48) - removed style.WindowFillAlphaDefault setting which was redundant. Bake default BG alpha inside style.Colors[ImGuiCol_WindowBg] and all other Bg color values. (ref github issue #337).
+ - 2016/04/03 (1.48) - renamed ImGuiCol_TooltipBg to ImGuiCol_PopupBg, used by popups/menus and tooltips. popups/menus were previously using ImGuiCol_WindowBg. (ref github issue #337)
- 2016/03/21 (1.48) - renamed GetWindowFont() to GetFont(), GetWindowFontSize() to GetFontSize(). Kept inline redirection function (will obsolete).
- 2016/03/02 (1.48) - InputText() completion/history/always callbacks: if you modify the text buffer manually (without using DeleteChars()/InsertChars() helper) you need to maintain the BufTextLen field. added an assert.
- 2016/01/23 (1.48) - fixed not honoring exact width passed to PushItemWidth(), previously it would add extra FramePadding.x*2 over that width. if you had manual pixel-perfect alignment in place it might affect you.
@@ -439,6 +441,7 @@
!- window: begin with *p_opened == false should return false.
- window: get size/pos helpers given names (see discussion in #249)
- window: a collapsed window can be stuck behind the main menu bar?
+ - window: when window is small, prioritize resize button over close button.
- window: detect extra End() call that pop the "Debug" window out and assert at call site instead of later.
- window/tooltip: allow to set the width of a tooltip to allow TextWrapped() etc. while keeping the height automatic.
- window: increase minimum size of a window with menus or fix the menu rendering so that it doesn't look odd.
@@ -448,15 +451,19 @@
- widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc.
- widgets: clean up widgets internal toward exposing everything.
- widgets: add disabled and read-only modes (#211)
- - main: considering adding EndFrame()/Init(). some constructs are awkward in the implementation because of the lack of them.
- - main: make it so that a frame with no window registered won't refocus every window on subsequent frames (~bump LastFrameActive of all windows).
+ - main: considering adding an Init() function? some constructs are awkward in the implementation because of the lack of them.
+!- main: make it so that a frame with no window registered won't refocus every window on subsequent frames (~bump LastFrameActive of all windows).
- main: IsItemHovered() make it more consistent for various type of widgets, widgets with multiple components, etc. also effectively IsHovered() region sometimes differs from hot region, e.g tree nodes
- main: IsItemHovered() info stored in a stack? so that 'if TreeNode() { Text; TreePop; } if IsHovered' return the hover state of the TreeNode?
- - input text: add ImGuiInputTextFlags_EnterToApply? (off #218)
+ - input text: clean up the mess caused by converting UTF-8 <> wchar. the code is rather inefficient right now.
- input text: reorganize event handling, allow CharFilter to modify buffers, allow multiple events? (#541)
+ - input text: flag to disable live update of the user buffer (also applies to float/int text input)
+ - input text: resize behavior - field could stretch when being edited? hover tooltip shows more text?
+ - input text: add ImGuiInputTextFlags_EnterToApply? (off #218)
- input text multi-line: don't directly call AddText() which does an unnecessary vertex reserve for character count prior to clipping. and/or more line-based clipping to AddText(). and/or reorganize TextUnformatted/RenderText for more efficiency for large text (e.g TextUnformatted could clip and log separately, etc).
- input text multi-line: way to dynamically grow the buffer without forcing the user to initially allocate for worse case (follow up on #200)
- input text multi-line: line numbers? status bar? (follow up on #200)
+ - input text: allow centering/positioning text so that ctrl+clicking Drag or Slider keeps the textual value at the same pixel position.
- input number: optional range min/max for Input*() functions
- input number: holding [-]/[+] buttons could increase the step speed non-linearly (or user-controlled)
- input number: use mouse wheel to step up/down
@@ -495,10 +502,11 @@
- statusbar: add a per-window status bar helper similar to what menubar does.
- tabs (#261, #351)
- separator: separator on the initial position of a window is not visible (cursorpos.y <= clippos.y)
- - color: the color helpers/typing is a mess and needs sorting out.
+!- color: the color helpers/typing is a mess and needs sorting out.
- color: add a better color picker (#346)
- node/graph editor (#306)
- pie menus patterns (#434)
+ - drag'n drop, dragging helpers (carry dragging info, visualize drag source before clicking, drop target, etc.) (#143, #479)
- plot: PlotLines() should use the polygon-stroke facilities (currently issues with averaging normals)
- plot: make it easier for user to draw extra stuff into the graph (e.g: draw basis, highlight certain points, 2d plots, multiple plots)
- plot: "smooth" automatic scale over time, user give an input 0.0(full user scale) 1.0(full derived from value)
@@ -510,14 +518,11 @@
- slider & drag: int data passing through a float
- drag float: up/down axis
- drag float: added leeway on edge (e.g. a few invisible steps past the clamp limits)
- - text edit: clean up the mess caused by converting UTF-8 <> wchar. the code is rather inefficient right now.
- - text edit: centered text for slider as input text so it matches typical positioning.
- - text edit: flag to disable live update of the user buffer.
- - text edit: field resize behavior - field could stretch when being edited? hover tooltip shows more text?
- tree node / optimization: avoid formatting when clipped.
- tree node: clarify spacing, perhaps provide API to query exact spacing. provide API to draw the primitive. same with Bullet().
- tree node: tree-node/header right-most side doesn't take account of horizontal scrolling.
- tree node: add treenode/treepush int variants? because (void*) cast from int warns on some platforms/settings
+ - tree node: try to apply scrolling at time of TreePop() if node was just opened and end of node is past scrolling limits?
- tree node / selectable render mismatch which is visible if you use them both next to each other (e.g. cf. property viewer)
- textwrapped: figure out better way to use TextWrapped() in an always auto-resize context (tooltip, etc.) (git issue #249)
- settings: write more decent code to allow saving/loading new fields
@@ -527,6 +532,7 @@
- style: color-box not always square?
- style: a concept of "compact style" that the end-user can easily rely on (e.g. PushStyleCompact()?) that maps to other settings? avoid implementing duplicate helpers such as SmallCheckbox(), etc.
- style: try to make PushStyleVar() more robust to incorrect parameters (to be more friendly to edit & continues situation).
+ - style/opt: PopStyleVar could be optimized by having GetStyleVar returns the type, using a table mapping stylevar enum to data type.
- style: global scale setting.
- text: simple markup language for color change?
- font: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier.
@@ -550,7 +556,8 @@
- style editor: have a more global HSV setter (e.g. alter hue on all elements). consider replacing active/hovered by offset in HSV space? (#438)
- style editor: color child window height expressed in multiple of line height.
- remote: make a system like RemoteImGui first-class citizen/project (#75)
- - drawlist: user probably can't call Clear() because we expect a texture to be pushed in the stack.
+!- demo: custom render demo pushes a clipping rectangle past parent window bounds. expose ImGui::PushClipRect() from imgui_internal.h?
+ - drawlist: end-user probably can't call Clear() directly because we expect a texture to be pushed in the stack.
- examples: directx9/directx11: save/restore device state more thoroughly.
- optimization: use another hash function than crc32, e.g. FNV1a
- optimization/render: merge command-lists with same clip-rect into one even if they aren't sequential? (as long as in-between clip rectangle don't overlap)?
@@ -689,13 +696,12 @@ ImGuiStyle::ImGuiStyle()
WindowMinSize = ImVec2(32,32); // Minimum window size
WindowRounding = 9.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows
WindowTitleAlign = ImGuiAlign_Left; // Alignment for title bar text
- ChildWindowRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular windows
+ ChildWindowRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular child windows
FramePadding = ImVec2(4,3); // Padding within a framed rectangle (used by most widgets)
FrameRounding = 0.0f; // Radius of frame corners rounding. Set to 0.0f to have rectangular frames (used by most widgets).
ItemSpacing = ImVec2(8,4); // Horizontal and vertical spacing between widgets/lines
ItemInnerSpacing = ImVec2(4,4); // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label)
TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much!
- WindowFillAlphaDefault = 0.70f; // Default alpha of window background, if not specified in ImGui::Begin()
IndentSpacing = 22.0f; // Horizontal spacing when e.g. entering a tree node
ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns
ScrollbarSize = 16.0f; // Width of the vertical scrollbar, Height of the horizontal scrollbar
@@ -710,8 +716,9 @@ ImGuiStyle::ImGuiStyle()
Colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f);
Colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f);
- Colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
+ Colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.70f);
Colors[ImGuiCol_ChildWindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
+ Colors[ImGuiCol_PopupBg] = ImVec4(0.05f, 0.05f, 0.10f, 0.90f);
Colors[ImGuiCol_Border] = ImVec4(0.70f, 0.70f, 0.70f, 0.65f);
Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
Colors[ImGuiCol_FrameBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.30f); // Background of checkbox, radio button, plot, slider, text input
@@ -749,7 +756,6 @@ ImGuiStyle::ImGuiStyle()
Colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f);
Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f);
- Colors[ImGuiCol_TooltipBg] = ImVec4(0.05f, 0.05f, 0.10f, 0.90f);
Colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f);
}
@@ -788,6 +794,14 @@ ImGuiIO::ImGuiIO()
GetClipboardTextFn = GetClipboardTextFn_DefaultImpl; // Platform dependent default implementations
SetClipboardTextFn = SetClipboardTextFn_DefaultImpl;
ImeSetInputScreenPosFn = ImeSetInputScreenPosFn_DefaultImpl;
+
+ // Set OS X style defaults based on __APPLE__ compile time flag
+#ifdef __APPLE__
+ WordMovementUsesAltKey = true; // OS X style: Text editing cursor movement using Alt instead of Ctrl
+ ShortcutsUseSuperKey = true; // OS X style: Shortcuts using Cmd/Super instead of Ctrl
+ DoubleClickSelectsWord = true; // OS X style: Double click selects by word instead of selecting whole text
+ MultiSelectUsesSuperKey = true; // OS X style: Multi-selection in lists uses Cmd/Super instead of Ctrl
+#endif
}
// Pass in translated ASCII characters for text input.
@@ -3126,9 +3140,8 @@ static ImRect GetVisibleRect()
void ImGui::BeginTooltip()
{
- ImGuiState& g = *GImGui;
ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize;
- ImGui::Begin("##Tooltip", NULL, ImVec2(0,0), g.Style.Colors[ImGuiCol_TooltipBg].w, flags);
+ ImGui::Begin("##Tooltip", NULL, flags);
}
void ImGui::EndTooltip()
@@ -3266,9 +3279,8 @@ static bool BeginPopupEx(const char* str_id, ImGuiWindowFlags extra_flags)
ImFormatString(name, 20, "##menu_%d", g.CurrentPopupStack.Size); // Recycle windows based on depth
else
ImFormatString(name, 20, "##popup_%08x", id); // Not recycling, so we can close/open during the same frame
- float alpha = 1.0f;
- bool opened = ImGui::Begin(name, NULL, ImVec2(0.0f, 0.0f), alpha, flags);
+ bool opened = ImGui::Begin(name, NULL, flags);
if (!(window->Flags & ImGuiWindowFlags_ShowBorders))
g.CurrentWindow->Flags &= ~ImGuiWindowFlags_ShowBorders;
if (!opened) // opened can be 'false' when the popup is completely clipped (e.g. zero size display)
@@ -3299,7 +3311,7 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_opened, ImGuiWindowFlags e
}
ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_Modal|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoSavedSettings;
- bool opened = ImGui::Begin(name, p_opened, ImVec2(0.0f, 0.0f), -1.0f, flags);
+ bool opened = ImGui::Begin(name, p_opened, flags);
if (!opened || (p_opened && !*p_opened)) // Opened can be 'false' when the popup is completely clipped (e.g. zero size display)
{
ImGui::EndPopup();
@@ -3379,8 +3391,7 @@ bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border,
char title[256];
ImFormatString(title, IM_ARRAYSIZE(title), "%s.%s", window->Name, str_id);
- const float alpha = 1.0f;
- bool ret = ImGui::Begin(title, NULL, size, alpha, flags);
+ bool ret = ImGui::Begin(title, NULL, size, -1.0f, flags);
if (!(window->Flags & ImGuiWindowFlags_ShowBorders))
GetCurrentWindow()->Flags &= ~ImGuiWindowFlags_ShowBorders;
@@ -3430,13 +3441,14 @@ bool ImGui::BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags ext
const ImGuiStyle& style = g.Style;
ImGui::PushStyleColor(ImGuiCol_ChildWindowBg, style.Colors[ImGuiCol_FrameBg]);
ImGui::PushStyleVar(ImGuiStyleVar_ChildWindowRounding, style.FrameRounding);
- return ImGui::BeginChild(id, size, false, ImGuiWindowFlags_NoMove | extra_flags);
+ ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding);
+ return ImGui::BeginChild(id, size, (g.CurrentWindow->Flags & ImGuiWindowFlags_ShowBorders) ? true : false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding | extra_flags);
}
void ImGui::EndChildFrame()
{
ImGui::EndChild();
- ImGui::PopStyleVar();
+ ImGui::PopStyleVar(2);
ImGui::PopStyleColor();
}
@@ -3679,10 +3691,6 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
window->RootWindow = g.CurrentWindowStack[root_idx];
window->RootNonPopupWindow = g.CurrentWindowStack[root_non_popup_idx]; // This is merely for displaying the TitleBgActive color.
- // Default alpha
- if (bg_alpha < 0.0f)
- bg_alpha = style.WindowFillAlphaDefault;
-
// When reusing window again multiple times a frame, just append content (don't need to setup again)
if (first_begin_of_the_frame)
{
@@ -3754,7 +3762,7 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
}
// Lock window padding so that altering the ShowBorders flag for children doesn't have side-effects.
- window->WindowPadding = ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup))) ? ImVec2(0,0) : style.WindowPadding;
+ window->WindowPadding = ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup))) ? ImVec2(0,0) : style.WindowPadding;
// Calculate auto-fit size
ImVec2 size_auto_fit;
@@ -3968,27 +3976,26 @@ bool ImGui::Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_
}
// Scrollbars
- window->ScrollbarY = (flags & ImGuiWindowFlags_ForceVerticalScrollbar) || ((window->SizeContents.y > window->Size.y + style.ItemSpacing.y) && !(flags & ImGuiWindowFlags_NoScrollbar));
- window->ScrollbarX = (flags & ImGuiWindowFlags_ForceHorizontalScrollbar) || ((window->SizeContents.x > window->Size.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar));
+ window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > window->Size.y + style.ItemSpacing.y) && !(flags & ImGuiWindowFlags_NoScrollbar));
+ window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > window->Size.x - (window->ScrollbarY ? style.ScrollbarSize : 0.0f) - window->WindowPadding.x) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar));
window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f);
window->BorderSize = (flags & ImGuiWindowFlags_ShowBorders) ? 1.0f : 0.0f;
// Window background
- if (bg_alpha > 0.0f)
- {
- ImGuiCol col_idx;
- if ((flags & ImGuiWindowFlags_ComboBox) != 0)
- col_idx = ImGuiCol_ComboBg;
- else if ((flags & ImGuiWindowFlags_Tooltip) != 0)
- col_idx = ImGuiCol_TooltipBg;
- else if ((flags & ImGuiWindowFlags_Popup) != 0)
- col_idx = ImGuiCol_WindowBg;
- else if ((flags & ImGuiWindowFlags_ChildWindow) != 0)
- col_idx = ImGuiCol_ChildWindowBg;
- else
- col_idx = ImGuiCol_WindowBg;
- window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, GetColorU32(col_idx, bg_alpha), window_rounding);
- }
+ // Default alpha
+ ImGuiCol bg_color_idx = ImGuiCol_WindowBg;
+ if ((flags & ImGuiWindowFlags_ComboBox) != 0)
+ bg_color_idx = ImGuiCol_ComboBg;
+ else if ((flags & ImGuiWindowFlags_Tooltip) != 0 || (flags & ImGuiWindowFlags_Popup) != 0)
+ bg_color_idx = ImGuiCol_PopupBg;
+ else if ((flags & ImGuiWindowFlags_ChildWindow) != 0)
+ bg_color_idx = ImGuiCol_ChildWindowBg;
+ ImVec4 bg_color = style.Colors[bg_color_idx];
+ if (bg_alpha >= 0.0f)
+ bg_color.w = bg_alpha;
+ bg_color.w *= style.Alpha;
+ if (bg_color.w > 0.0f)
+ window->DrawList->AddRectFilled(window->Pos, window->Pos+window->Size, ColorConvertFloat4ToU32(bg_color), window_rounding);
// Title bar
if (!(flags & ImGuiWindowFlags_NoTitleBar))
@@ -4510,6 +4517,7 @@ const char* ImGui::GetStyleColName(ImGuiCol idx)
case ImGuiCol_TextDisabled: return "TextDisabled";
case ImGuiCol_WindowBg: return "WindowBg";
case ImGuiCol_ChildWindowBg: return "ChildWindowBg";
+ case ImGuiCol_PopupBg: return "PopupBg";
case ImGuiCol_Border: return "Border";
case ImGuiCol_BorderShadow: return "BorderShadow";
case ImGuiCol_FrameBg: return "FrameBg";
@@ -4547,7 +4555,6 @@ const char* ImGui::GetStyleColName(ImGuiCol idx)
case ImGuiCol_PlotHistogram: return "PlotHistogram";
case ImGuiCol_PlotHistogramHovered: return "PlotHistogramHovered";
case ImGuiCol_TextSelectedBg: return "TextSelectedBg";
- case ImGuiCol_TooltipBg: return "TooltipBg";
case ImGuiCol_ModalWindowDarkening: return "ModalWindowDarkening";
}
IM_ASSERT(0);
@@ -7091,8 +7098,18 @@ 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 c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|'; }
-#define STB_TEXTEDIT_IS_SPACE(CH) ( ImCharIsSpace((unsigned int)CH) || is_separator((unsigned int)CH) )
+static bool is_separator(unsigned int c) { return ImCharIsSpace(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 is_word_boundary_from_left(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) { while (idx >= 0 && !is_word_boundary_from_right(obj, idx)) idx--; return idx < 0 ? 0 : idx; }
+#ifdef __APPLE__ // FIXME: Move setting to IO structure
+static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) { int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_left(obj, idx)) idx++; return idx > len ? len : idx; }
+#else
+static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) { int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_right(obj, idx)) idx++; return idx > len ? len : idx; }
+#endif
+#define STB_TEXTEDIT_MOVEWORDLEFT STB_TEXTEDIT_MOVEWORDLEFT_IMPL // They need to be #define for stb_textedit.h
+#define STB_TEXTEDIT_MOVEWORDRIGHT STB_TEXTEDIT_MOVEWORDRIGHT_IMPL
+
static void STB_TEXTEDIT_DELETECHARS(STB_TEXTEDIT_STRING* obj, int pos, int n)
{
ImWchar* dst = obj->Text.Data + pos;
@@ -7289,7 +7306,6 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
return false;
}
draw_window = GetCurrentWindow();
- draw_window->DC.CursorPos += style.FramePadding;
size.x -= draw_window->ScrollbarSizes.x;
}
else
@@ -7322,6 +7338,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
const bool is_ctrl_down = io.KeyCtrl;
const bool is_shift_down = io.KeyShift;
const bool is_alt_down = io.KeyAlt;
+ const bool is_super_down = io.KeySuper;
const bool focus_requested = FocusableItemRegister(window, g.ActiveId == id, (flags & (ImGuiInputTextFlags_CallbackCompletion|ImGuiInputTextFlags_AllowTabInput)) == 0); // Using completion callback disable keyboard tabbing
const bool focus_requested_by_code = focus_requested && (window->FocusIdxAllCounter == window->FocusIdxAllRequestCurrent);
const bool focus_requested_by_tab = focus_requested && !focus_requested_by_code;
@@ -7409,11 +7426,17 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
const float mouse_x = (g.IO.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + edit_state.ScrollX;
const float mouse_y = (is_multiline ? (g.IO.MousePos.y - draw_window->DC.CursorPos.y - style.FramePadding.y) : (g.FontSize*0.5f));
- if (select_all || (hovered && io.MouseDoubleClicked[0]))
+ if (select_all || (hovered && !io.DoubleClickSelectsWord && io.MouseDoubleClicked[0]))
{
edit_state.SelectAll();
edit_state.SelectedAllMouseLock = true;
}
+ else if (hovered && io.DoubleClickSelectsWord && io.MouseDoubleClicked[0])
+ {
+ // 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);
+ }
else if (io.MouseClicked[0] && !edit_state.SelectedAllMouseLock)
{
stb_textedit_click(&edit_state, &edit_state.StbState, mouse_x, mouse_y);
@@ -7451,9 +7474,11 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
// Handle various key-presses
bool cancel_edit = false;
const int k_mask = (is_shift_down ? STB_TEXTEDIT_K_SHIFT : 0);
- const bool is_ctrl_only = is_ctrl_down && !is_alt_down && !is_shift_down;
- if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); }
- else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); }
+ const bool is_shortcutkey_only = (io.ShortcutsUseSuperKey ? (is_super_down && !is_alt_down && !is_shift_down && !is_ctrl_down) : (is_ctrl_down && !is_alt_down && !is_shift_down && !is_super_down));
+ const bool is_wordmove_key_down = (io.WordMovementUsesAltKey ? io.KeyAlt : io.KeyCtrl);
+
+ if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed(is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT | k_mask : STB_TEXTEDIT_K_LEFT | k_mask); }
+ else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed(is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT | k_mask : STB_TEXTEDIT_K_RIGHT | k_mask); }
else if (is_multiline && IsKeyPressedMap(ImGuiKey_UpArrow)) { if (is_ctrl_down) SetWindowScrollY(draw_window, draw_window->Scroll.y - g.FontSize); else edit_state.OnKeyPressed(STB_TEXTEDIT_K_UP | k_mask); }
else if (is_multiline && IsKeyPressedMap(ImGuiKey_DownArrow)) { if (is_ctrl_down) SetWindowScrollY(draw_window, draw_window->Scroll.y + g.FontSize); else edit_state.OnKeyPressed(STB_TEXTEDIT_K_DOWN| k_mask); }
else if (IsKeyPressedMap(ImGuiKey_Home)) { edit_state.OnKeyPressed(is_ctrl_down ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); }
@@ -7481,11 +7506,11 @@ 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)) { SetActiveID(0); cancel_edit = true; }
- else if (is_ctrl_only && IsKeyPressedMap(ImGuiKey_Z) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); edit_state.ClearSelection(); }
- else if (is_ctrl_only && IsKeyPressedMap(ImGuiKey_Y) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); edit_state.ClearSelection(); }
- else if (is_ctrl_only && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); edit_state.CursorFollow = true; }
- else if (is_ctrl_only && !is_password && ((IsKeyPressedMap(ImGuiKey_X) && is_editable) || IsKeyPressedMap(ImGuiKey_C)) && (!is_multiline || edit_state.HasSelection()))
+ else if (IsKeyPressedMap(ImGuiKey_Escape)) { SetActiveID(0); cancel_edit = true; }
+ else if (is_shortcutkey_only && IsKeyPressedMap(ImGuiKey_Z) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); edit_state.ClearSelection(); }
+ else if (is_shortcutkey_only && IsKeyPressedMap(ImGuiKey_Y) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); edit_state.ClearSelection(); }
+ else if (is_shortcutkey_only && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); edit_state.CursorFollow = true; }
+ else if (is_shortcutkey_only && !is_password && ((IsKeyPressedMap(ImGuiKey_X) && is_editable) || IsKeyPressedMap(ImGuiKey_C)) && (!is_multiline || edit_state.HasSelection()))
{
// Cut, Copy
const bool cut = IsKeyPressedMap(ImGuiKey_X);
@@ -7507,7 +7532,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2
stb_textedit_cut(&edit_state, &edit_state.StbState);
}
}
- else if (is_ctrl_only && IsKeyPressedMap(ImGuiKey_V) && is_editable)
+ else if (is_shortcutkey_only && IsKeyPressedMap(ImGuiKey_V) && is_editable)
{
// Paste
if (g.IO.GetClipboardTextFn)
@@ -8471,7 +8496,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled)
bool want_open = false, want_close = false;
if (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu))
{
- // Implement http://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown to avoid using timers so menus feel more reactive.
+ // Implement http://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown to avoid using timers, so menus feels more reactive.
bool moving_within_opened_triangle = false;
if (g.HoveredWindow == window && g.OpenedPopupStack.Size > g.CurrentPopupStack.Size && g.OpenedPopupStack[g.CurrentPopupStack.Size].ParentWindow == window)
{
diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h
index 639891c2028..c8d223db39d 100644
--- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h
+++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui.h
@@ -105,7 +105,6 @@ namespace ImGui
IMGUI_API ImGuiStyle& GetStyle();
IMGUI_API ImDrawData* GetDrawData(); // same value as passed to your io.RenderDrawListsFn() function. valid after Render() and until the next call to NewFrame()
IMGUI_API void NewFrame(); // start a new ImGui frame, you can submit any command from this point until NewFrame()/Render().
- IMGUI_API void EndFrame(); // ends the ImGui frame. automatically called by Render()!
IMGUI_API void Render(); // ends the ImGui frame, finalize rendering data, then call your io.RenderDrawListsFn() function if set.
IMGUI_API void Shutdown();
IMGUI_API void ShowUserGuide(); // help block
@@ -114,11 +113,11 @@ namespace ImGui
IMGUI_API void ShowMetricsWindow(bool* opened = NULL); // metrics window for debugging ImGui
// Window
- IMGUI_API bool Begin(const char* name, bool* p_opened = NULL, ImGuiWindowFlags flags = 0); // see .cpp for details. return false when window is collapsed, so you can early out in your code. 'bool* p_opened' creates a widget on the upper-right to close the window (which sets your bool to false).
- IMGUI_API bool Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_use, float bg_alpha = -1.0f, ImGuiWindowFlags flags = 0); // this is the older/longer API. the extra parameters aren't very relevant. call SetNextWindowSize() instead if you want to set a window size. For regular windows, 'size_on_first_use' only applies to the first time EVER the window is created and probably not what you want! maybe obsolete this API eventually.
- IMGUI_API void End();
- IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // begin a scrolling region. size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). size>0.0f: fixed size. each axis can use a different mode, e.g. ImVec2(0,400).
- IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // "
+ IMGUI_API bool Begin(const char* name, bool* p_opened = NULL, ImGuiWindowFlags flags = 0); // push window to the stack and start appending to it. see .cpp for details. return false when window is collapsed, so you can early out in your code. 'bool* p_opened' creates a widget on the upper-right to close the window (which sets your bool to false).
+ IMGUI_API bool Begin(const char* name, bool* p_opened, const ImVec2& size_on_first_use, float bg_alpha = -1.0f, ImGuiWindowFlags flags = 0); // OBSOLETE. this is the older/longer API. the extra parameters aren't very relevant. call SetNextWindowSize() instead if you want to set a window size. For regular windows, 'size_on_first_use' only applies to the first time EVER the window is created and probably not what you want! might obsolete this API eventually.
+ IMGUI_API void End(); // finish appending to current window, pop it off the window stack.
+ IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // begin a scrolling region. size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). size>0.0f: fixed size. each axis can use a different mode, e.g. ImVec2(0,400).
+ IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags extra_flags = 0); // "
IMGUI_API void EndChild();
IMGUI_API ImVec2 GetContentRegionMax(); // current content boundaries (typically window boundaries including scrolling, or current column boundaries), in windows coordinates
IMGUI_API ImVec2 GetContentRegionAvail(); // == GetContentRegionMax() - GetCursorPos()
@@ -467,11 +466,12 @@ enum ImGuiWindowFlags_
ImGuiWindowFlags_NoSavedSettings = 1 << 8, // Never load/save settings in .ini file
ImGuiWindowFlags_NoInputs = 1 << 9, // Disable catching mouse or keyboard inputs
ImGuiWindowFlags_MenuBar = 1 << 10, // Has a menu-bar
- ImGuiWindowFlags_HorizontalScrollbar = 1 << 11, // Allow horizontal scrollbar to appear (off by default). You need to use SetNextWindowContentSize(ImVec2(width,0.0f)); prior to calling Begin() to specify width. Read code in imgui_demo in the "Horizontal Scrolling" section.
+ ImGuiWindowFlags_HorizontalScrollbar = 1 << 11, // Allow horizontal scrollbar to appear (off by default). You may use SetNextWindowContentSize(ImVec2(width,0.0f)); prior to calling Begin() to specify width. Read code in imgui_demo in the "Horizontal Scrolling" section.
ImGuiWindowFlags_NoFocusOnAppearing = 1 << 12, // Disable taking focus when transitioning from hidden to visible state
ImGuiWindowFlags_NoBringToFrontOnFocus = 1 << 13, // Disable bringing window to front when taking focus (e.g. clicking on it or programatically giving it focus)
- ImGuiWindowFlags_ForceVerticalScrollbar = 1 << 14, // Always show vertical scrollbar (even if ContentSize.y < Size.y)
- ImGuiWindowFlags_ForceHorizontalScrollbar=1 << 15, // Always show horizontal scrollbar (even if ContentSize.x < Size.x)
+ ImGuiWindowFlags_AlwaysVerticalScrollbar= 1 << 14, // Always show vertical scrollbar (even if ContentSize.y < Size.y)
+ ImGuiWindowFlags_AlwaysHorizontalScrollbar=1<< 15, // Always show horizontal scrollbar (even if ContentSize.x < Size.x)
+ ImGuiWindowFlags_AlwaysUseWindowPadding = 1 << 16, // Ensure child windows without border uses style.WindowPadding (ignored by default for non-bordered child windows, because more convenient)
// [Internal]
ImGuiWindowFlags_ChildWindow = 1 << 20, // Don't use! For internal use by BeginChild()
ImGuiWindowFlags_ChildWindowAutoFitX = 1 << 21, // Don't use! For internal use by BeginChild()
@@ -546,8 +546,9 @@ enum ImGuiCol_
{
ImGuiCol_Text,
ImGuiCol_TextDisabled,
- ImGuiCol_WindowBg,
- ImGuiCol_ChildWindowBg,
+ ImGuiCol_WindowBg, // Background of normal windows
+ ImGuiCol_ChildWindowBg, // Background of child windows
+ ImGuiCol_PopupBg, // Background of popups, menus, tooltips windows
ImGuiCol_Border,
ImGuiCol_BorderShadow,
ImGuiCol_FrameBg, // Background of checkbox, radio button, plot, slider, text input
@@ -585,7 +586,6 @@ enum ImGuiCol_
ImGuiCol_PlotHistogram,
ImGuiCol_PlotHistogramHovered,
ImGuiCol_TextSelectedBg,
- ImGuiCol_TooltipBg,
ImGuiCol_ModalWindowDarkening, // darken entire screen when a modal window is active
ImGuiCol_COUNT
};
@@ -664,7 +664,6 @@ struct ImGuiStyle
ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines
ImVec2 ItemInnerSpacing; // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label)
ImVec2 TouchExtraPadding; // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much!
- float WindowFillAlphaDefault; // Default alpha of window background, if not specified in ImGui::Begin()
float IndentSpacing; // Horizontal indentation when e.g. entering a tree node
float ColumnsMinSpacing; // Minimum horizontal spacing between two columns
float ScrollbarSize; // Width of the vertical scrollbar, Height of the horizontal scrollbar
@@ -710,6 +709,12 @@ struct ImGuiIO
ImVec2 DisplayVisibleMin; // <unset> (0.0f,0.0f) // If you use DisplaySize as a virtual space larger than your screen, set DisplayVisibleMin/Max to the visible area.
ImVec2 DisplayVisibleMax; // <unset> (0.0f,0.0f) // If the values are the same, we defaults to Min=(0.0f) and Max=DisplaySize
+ // Advanced/subtle behaviors
+ bool WordMovementUsesAltKey; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl
+ bool ShortcutsUseSuperKey; // = defined(__APPLE__) // OS X style: Shortcuts using Cmd/Super instead of Ctrl
+ bool DoubleClickSelectsWord; // = defined(__APPLE__) // OS X style: Double click selects by word instead of selecting whole text
+ bool MultiSelectUsesSuperKey; // = defined(__APPLE__) // OS X style: Multi-selection in lists uses Cmd/Super instead of Ctrl [unused yet]
+
//------------------------------------------------------------------
// User Functions
//------------------------------------------------------------------
@@ -745,6 +750,7 @@ struct ImGuiIO
bool KeyCtrl; // Keyboard modifier pressed: Control
bool KeyShift; // Keyboard modifier pressed: Shift
bool KeyAlt; // Keyboard modifier pressed: Alt
+ bool KeySuper; // Keyboard modifier pressed: Cmd/Super/Windows
bool KeysDown[512]; // Keyboard keys that are pressed (in whatever storage order you naturally have access to keyboard data)
ImWchar InputCharacters[16+1]; // List of characters input (translated by user from keypress+keyboard state). Fill using AddInputCharacter() helper.
@@ -982,7 +988,8 @@ struct ImGuiTextEditCallbackData
bool HasSelection() const { return SelectionStart != SelectionEnd; }
};
-// ImColor() is just a helper that implicity converts to either ImU32 (packed 4x1 byte) or ImVec4 (4x1 float)
+// ImColor() helper to implicity converts colors to either ImU32 (packed 4x1 byte) or ImVec4 (4x1 float)
+// Avoid storing ImColor! Store either u32 of ImVec4. This is not a full-featured color class.
// None of the ImGui API are using ImColor directly but you can use it as a convenience to pass colors in either ImU32 or ImVec4 formats.
struct ImColor
{
diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp
index 533d23b4510..ad6e7aa6ff0 100644
--- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp
+++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp
@@ -139,7 +139,6 @@ void ImGui::ShowTestWindow(bool* p_opened)
static bool no_scrollbar = false;
static bool no_collapse = false;
static bool no_menu = false;
- static float bg_alpha = -0.01f; // <0: default
// Demonstrate the various window flags. Typically you would just use the default.
ImGuiWindowFlags window_flags = 0;
@@ -150,7 +149,8 @@ void ImGui::ShowTestWindow(bool* p_opened)
if (no_scrollbar) window_flags |= ImGuiWindowFlags_NoScrollbar;
if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse;
if (!no_menu) window_flags |= ImGuiWindowFlags_MenuBar;
- if (!ImGui::Begin("ImGui Demo", p_opened, ImVec2(550,680), bg_alpha, window_flags))
+ ImGui::SetNextWindowSize(ImVec2(550,680), ImGuiSetCond_FirstUseEver);
+ if (!ImGui::Begin("ImGui Demo", p_opened, window_flags))
{
// Early out if the window is collapsed, as an optimization.
ImGui::End();
@@ -211,10 +211,6 @@ void ImGui::ShowTestWindow(bool* p_opened)
ImGui::Checkbox("No collapse", &no_collapse);
ImGui::Checkbox("No menu", &no_menu);
- ImGui::PushItemWidth(100);
- ImGui::DragFloat("Window Fill Alpha", &bg_alpha, 0.005f, -0.01f, 1.0f, bg_alpha < 0.0f ? "(default)" : "%.3f"); // Not exposing zero here so user doesn't "lose" the UI (zero alpha clips all widgets). But application code could have a toggle to switch between zero and non-zero.
- ImGui::PopItemWidth();
-
if (ImGui::TreeNode("Style"))
{
ImGui::ShowStyleEditor();
@@ -1500,7 +1496,7 @@ void ImGui::ShowTestWindow(bool* p_opened)
ImGui::Text("Keys down:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (io.KeysDownDuration[i] >= 0.0f) { ImGui::SameLine(); ImGui::Text("%d (%.02f secs)", i, io.KeysDownDuration[i]); }
ImGui::Text("Keys pressed:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyPressed(i)) { ImGui::SameLine(); ImGui::Text("%d", i); }
ImGui::Text("Keys release:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyReleased(i)) { ImGui::SameLine(); ImGui::Text("%d", i); }
- ImGui::Text("KeyMods: %s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : "");
+ ImGui::Text("KeyMods: %s%s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : "", io.KeySuper ? "SUPER " : "");
ImGui::Text("WantCaptureMouse: %s", io.WantCaptureMouse ? "true" : "false");
ImGui::Text("WantCaptureKeyboard: %s", io.WantCaptureKeyboard ? "true" : "false");
@@ -1561,7 +1557,6 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, FLT_MAX, NULL, 2.0f);
if (style.CurveTessellationTol < 0.0f) style.CurveTessellationTol = 0.10f;
ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI (zero alpha clips all widgets). But application code could have a toggle to switch between zero and non-zero.
- ImGui::DragFloat("Window Fill Alpha Default", &style.WindowFillAlphaDefault, 0.005f, 0.0f, 1.0f, "%.2f");
ImGui::PopItemWidth();
ImGui::TreePop();
}
@@ -1618,7 +1613,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
static ImGuiTextFilter filter;
filter.Draw("Filter colors", 200);
- ImGui::BeginChild("#colors", ImVec2(0, 300), true);
+ ImGui::BeginChild("#colors", ImVec2(0, 300), true, ImGuiWindowFlags_AlwaysVerticalScrollbar);
ImGui::PushItemWidth(-160);
ImGui::ColorEditMode(edit_mode);
for (int i = 0; i < ImGuiCol_COUNT; i++)
diff --git a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h
index 9c42da079dd..0f654a541a7 100644
--- a/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h
+++ b/3rdparty/bgfx/3rdparty/ocornut-imgui/imgui_internal.h
@@ -679,6 +679,8 @@ namespace ImGui
IMGUI_API ImGuiWindow* FindWindowByName(const char* name);
IMGUI_API void FocusWindow(ImGuiWindow* window);
+ IMGUI_API void EndFrame(); // Ends the ImGui frame. Automatically called by Render()! you most likely don't need to ever call that yourself directly. If you don't need to render you can call EndFrame() but you'll have wasted CPU already. If you don't need to render, don't create any windows instead!
+
IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window);
IMGUI_API void SetHoveredID(ImGuiID id);
IMGUI_API void KeepAliveID(ImGuiID id);
diff --git a/3rdparty/bgfx/3rdparty/stb/stb_image.c b/3rdparty/bgfx/3rdparty/stb/stb_image.c
index e98f211dcd8..401895aed58 100644
--- a/3rdparty/bgfx/3rdparty/stb/stb_image.c
+++ b/3rdparty/bgfx/3rdparty/stb/stb_image.c
@@ -37,13 +37,16 @@
TGA (not sure what subset, if a subset)
BMP non-1bpp, non-RLE
- PSD (composited view only, no extra channels)
+ PSD (composited view only, no extra channels, 8/16 bit-per-channel)
GIF (*comp always reports as 4-channel)
HDR (radiance rgbE format)
PIC (Softimage PIC)
PNM (PPM and PGM binary only)
+ Animated GIF still needs a proper API, but here's one way to do it:
+ http://gist.github.com/urraka/685d9a6340b26b830d49
+
- decode from memory or through FILE (define STBI_NO_STDIO to remove code)
- decode from arbitrary I/O callbacks
- SIMD acceleration on x86/x64 (SSE2) and ARM (NEON)
@@ -155,6 +158,17 @@
Latest revision history:
+ 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
+ 2.11 (2016-04-02) 16-bit PNGS; enable SSE2 in non-gcc x64
+ RGB-format JPEG; remove white matting in PSD;
+ allocate large structures on the stack;
+ correct channel count for PNG & BMP
+ 2.10 (2016-01-22) avoid warning introduced in 2.09
+ 2.09 (2016-01-16) 16-bit TGA; comments in PNM files; STBI_REALLOC_SIZED
+ 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA
+ 2.07 (2015-09-13) partial animated GIF support
+ limited 16-bit PSD support
+ minor bugs, code cleanup, and compiler warnings
2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value
2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning
2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit
@@ -170,56 +184,47 @@
STBI_MALLOC,STBI_REALLOC,STBI_FREE
STBI_NO_*, STBI_ONLY_*
GIF bugfix
- 1.48 (2014-12-14) fix incorrectly-named assert()
- 1.47 (2014-12-14) 1/2/4-bit PNG support (both grayscale and paletted)
- optimize PNG
- fix bug in interlaced PNG with user-specified channel count
See end of file for full revision history.
============================ Contributors =========================
- Image formats Bug fixes & warning fixes
- Sean Barrett (jpeg, png, bmp) Marc LeBlanc
- Nicolas Schulz (hdr, psd) Christpher Lloyd
- Jonathan Dummer (tga) Dave Moore
- Jean-Marc Lienher (gif) Won Chun
- Tom Seddon (pic) the Horde3D community
- Thatcher Ulrich (psd) Janez Zemva
- Ken Miller (pgm, ppm) Jonathan Blow
- Laurent Gomila
- Aruelien Pocheville
- Extensions, features Ryamond Barbiero
- Jetro Lauha (stbi_info) David Woo
- Martin "SpartanJ" Golini (stbi_info) Martin Golini
- James "moose2000" Brown (iPhone PNG) Roy Eltham
- Ben "Disch" Wenger (io callbacks) Luke Graham
- Omar Cornut (1/2/4-bit PNG) Thomas Ruf
- Nicolas Guillemot (vertical flip) John Bartholomew
- Ken Hamada
- Optimizations & bugfixes Cort Stratton
- Fabian "ryg" Giesen Blazej Dariusz Roszkowski
- Arseny Kapoulkine Thibault Reuille
- Paul Du Bois
- Guillaume George
- If your name should be here but Jerry Jansson
- isn't, let Sean know. Hayaki Saito
- Johan Duparc
- Ronny Chevalier
- Michal Cichon
- Tero Hanninen
- Sergio Gonzalez
- Cass Everitt
- Engin Manap
- Martins Mozeiko
- Joseph Thomson
- Phil Jordan
-
-License:
- This software is in the public domain. Where that dedication is not
- recognized, you are granted a perpetual, irrevocable license to copy
- and modify this file however you want.
+ Image formats Extensions, features
+ Sean Barrett (jpeg, png, bmp) Jetro Lauha (stbi_info)
+ Nicolas Schulz (hdr, psd) Martin "SpartanJ" Golini (stbi_info)
+ Jonathan Dummer (tga) James "moose2000" Brown (iPhone PNG)
+ Jean-Marc Lienher (gif) Ben "Disch" Wenger (io callbacks)
+ Tom Seddon (pic) Omar Cornut (1/2/4-bit PNG)
+ Thatcher Ulrich (psd) Nicolas Guillemot (vertical flip)
+ Ken Miller (pgm, ppm) Richard Mitton (16-bit PSD)
+ urraka@github (animated gif) Junggon Kim (PNM comments)
+ Daniel Gibson (16-bit TGA)
+
+ Optimizations & bugfixes
+ Fabian "ryg" Giesen
+ Arseny Kapoulkine
+
+ Bug & warning fixes
+ Marc LeBlanc David Woo Guillaume George Martins Mozeiko
+ Christpher Lloyd Martin Golini Jerry Jansson Joseph Thomson
+ Dave Moore Roy Eltham Hayaki Saito Phil Jordan
+ Won Chun Luke Graham Johan Duparc Nathan Reed
+ the Horde3D community Thomas Ruf Ronny Chevalier Nick Verigakis
+ Janez Zemva John Bartholomew Michal Cichon svdijk@github
+ Jonathan Blow Ken Hamada Tero Hanninen Baldur Karlsson
+ Laurent Gomila Cort Stratton Sergio Gonzalez romigrou@github
+ Aruelien Pocheville Thibault Reuille Cass Everitt Matthew Gregan
+ Ryamond Barbiero Paul Du Bois Engin Manap snagar@github
+ Michaelangel007@github Oriol Ferrer Mesia socks-the-fox
+ Blazej Dariusz Roszkowski
+
+
+LICENSE
+
+This software is dual-licensed to the public domain and under the following
+license: you are granted a perpetual, irrevocable license to copy, modify,
+publish, and distribute this file as you see fit.
*/
@@ -462,12 +467,12 @@ STBIDEF stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y,
#ifndef STBI_NO_HDR
STBIDEF void stbi_hdr_to_ldr_gamma(float gamma);
STBIDEF void stbi_hdr_to_ldr_scale(float scale);
-#endif
+#endif // STBI_NO_HDR
#ifndef STBI_NO_LINEAR
STBIDEF void stbi_ldr_to_hdr_gamma(float gamma);
STBIDEF void stbi_ldr_to_hdr_scale(float scale);
-#endif // STBI_NO_HDR
+#endif // STBI_NO_LINEAR
// stbi_is_hdr is always defined, but always returns false if STBI_NO_HDR
STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user);
@@ -631,18 +636,22 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
#define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y))))
#endif
-#if defined(STBI_MALLOC) && defined(STBI_FREE) && defined(STBI_REALLOC)
+#if defined(STBI_MALLOC) && defined(STBI_FREE) && (defined(STBI_REALLOC) || defined(STBI_REALLOC_SIZED))
// ok
-#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC)
+#elif !defined(STBI_MALLOC) && !defined(STBI_FREE) && !defined(STBI_REALLOC) && !defined(STBI_REALLOC_SIZED)
// ok
#else
-#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC."
+#error "Must define all or none of STBI_MALLOC, STBI_FREE, and STBI_REALLOC (or STBI_REALLOC_SIZED)."
#endif
#ifndef STBI_MALLOC
-#define STBI_MALLOC(sz) malloc(sz)
-#define STBI_REALLOC(p,sz) realloc(p,sz)
-#define STBI_FREE(p) free(p)
+#define STBI_MALLOC(sz) malloc(sz)
+#define STBI_REALLOC(p,newsz) realloc(p,newsz)
+#define STBI_FREE(p) free(p)
+#endif
+
+#ifndef STBI_REALLOC_SIZED
+#define STBI_REALLOC_SIZED(p,oldsz,newsz) STBI_REALLOC(p,newsz)
#endif
// x86/x64 detection
@@ -676,7 +685,7 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
#define STBI_NO_SIMD
#endif
-#if !defined(STBI_NO_SIMD) && defined(STBI__X86_TARGET)
+#if !defined(STBI_NO_SIMD) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET))
#define STBI_SSE2
#include <emmintrin.h>
@@ -761,7 +770,7 @@ typedef struct
stbi_uc buffer_start[128];
stbi_uc *img_buffer, *img_buffer_end;
- stbi_uc *img_buffer_original;
+ stbi_uc *img_buffer_original, *img_buffer_original_end;
} stbi__context;
@@ -773,7 +782,7 @@ static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len)
s->io.read = NULL;
s->read_from_callbacks = 0;
s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer;
- s->img_buffer_end = (stbi_uc *) buffer+len;
+ s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len;
}
// initialize a callback-based context
@@ -785,6 +794,7 @@ static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *
s->read_from_callbacks = 1;
s->img_buffer_original = s->buffer_start;
stbi__refill_buffer(s);
+ s->img_buffer_original_end = s->img_buffer_end;
}
#ifndef STBI_NO_STDIO
@@ -826,6 +836,7 @@ static void stbi__rewind(stbi__context *s)
// but we just rewind to the beginning of the initial buffer, because
// we only use it after doing 'test', which only ever looks at at most 92 bytes
s->img_buffer = s->img_buffer_original;
+ s->img_buffer_end = s->img_buffer_original_end;
}
#ifndef STBI_NO_JPEG
@@ -913,8 +924,8 @@ static void *stbi__malloc(size_t size)
#define stbi__err(x,y) stbi__err(x)
#endif
-#define stbi__errpf(x,y) ((float *) (stbi__err(x,y)?NULL:NULL))
-#define stbi__errpuc(x,y) ((unsigned char *) (stbi__err(x,y)?NULL:NULL))
+#define stbi__errpf(x,y) ((float *)(size_t) (stbi__err(x,y)?NULL:NULL))
+#define stbi__errpuc(x,y) ((unsigned char *)(size_t) (stbi__err(x,y)?NULL:NULL))
STBIDEF void stbi_image_free(void *retval_from_stbi_load)
{
@@ -1001,6 +1012,7 @@ static unsigned char *stbi__load_flip(stbi__context *s, int *x, int *y, int *com
return result;
}
+#ifndef STBI_NO_HDR
static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp)
{
if (stbi__vertically_flip_on_load && result != NULL) {
@@ -1021,7 +1033,7 @@ static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, in
}
}
}
-
+#endif
#ifndef STBI_NO_STDIO
@@ -1165,6 +1177,7 @@ STBIDEF int stbi_is_hdr_from_file(FILE *f)
stbi__start_file(&s,f);
return stbi__hdr_test(&s);
#else
+ STBI_NOTUSED(f);
return 0;
#endif
}
@@ -1177,18 +1190,21 @@ STBIDEF int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void
stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
return stbi__hdr_test(&s);
#else
+ STBI_NOTUSED(clbk);
+ STBI_NOTUSED(user);
return 0;
#endif
}
-static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f;
+#ifndef STBI_NO_LINEAR
static float stbi__l2h_gamma=2.2f, stbi__l2h_scale=1.0f;
-#ifndef STBI_NO_LINEAR
STBIDEF void stbi_ldr_to_hdr_gamma(float gamma) { stbi__l2h_gamma = gamma; }
STBIDEF void stbi_ldr_to_hdr_scale(float scale) { stbi__l2h_scale = scale; }
#endif
+static float stbi__h2l_gamma_i=1.0f/2.2f, stbi__h2l_scale_i=1.0f;
+
STBIDEF void stbi_hdr_to_ldr_gamma(float gamma) { stbi__h2l_gamma_i = 1/gamma; }
STBIDEF void stbi_hdr_to_ldr_scale(float scale) { stbi__h2l_scale_i = 1/scale; }
@@ -1297,17 +1313,23 @@ static stbi__uint32 stbi__get32be(stbi__context *s)
return (z << 16) + stbi__get16be(s);
}
+#if defined(STBI_NO_BMP) && defined(STBI_NO_TGA) && defined(STBI_NO_GIF)
+// nothing
+#else
static int stbi__get16le(stbi__context *s)
{
int z = stbi__get8(s);
return z + (stbi__get8(s) << 8);
}
+#endif
+#ifndef STBI_NO_BMP
static stbi__uint32 stbi__get32le(stbi__context *s)
{
stbi__uint32 z = stbi__get16le(s);
return z + (stbi__get16le(s) << 16);
}
+#endif
#define STBI__BYTECAST(x) ((stbi_uc) ((x) & 255)) // truncate int to byte without warnings
@@ -1497,6 +1519,7 @@ typedef struct
int succ_high;
int succ_low;
int eob_run;
+ int rgb;
int scan_n, order[4];
int restart_interval, todo;
@@ -2708,11 +2731,17 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
if (Lf != 8+3*s->img_n) return stbi__err("bad SOF len","Corrupt JPEG");
+ z->rgb = 0;
for (i=0; i < s->img_n; ++i) {
+ static unsigned char rgb[3] = { 'R', 'G', 'B' };
z->img_comp[i].id = stbi__get8(s);
if (z->img_comp[i].id != i+1) // JFIF requires
- if (z->img_comp[i].id != i) // some version of jpegtran outputs non-JFIF-compliant files!
- return stbi__err("bad component ID","Corrupt JPEG");
+ if (z->img_comp[i].id != i) { // some version of jpegtran outputs non-JFIF-compliant files!
+ // somethings output this (see http://fileformats.archiveteam.org/wiki/JPEG#Color_format)
+ if (z->img_comp[i].id != rgb[i])
+ return stbi__err("bad component ID","Corrupt JPEG");
+ ++z->rgb;
+ }
q = stbi__get8(s);
z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return stbi__err("bad H","Corrupt JPEG");
z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return stbi__err("bad V","Corrupt JPEG");
@@ -2751,7 +2780,7 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
if (z->img_comp[i].raw_data == NULL) {
for(--i; i >= 0; --i) {
STBI_FREE(z->img_comp[i].raw_data);
- z->img_comp[i].data = NULL;
+ z->img_comp[i].raw_data = NULL;
}
return stbi__err("outofmem", "Out of memory");
}
@@ -3118,7 +3147,7 @@ static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc cons
// so just accelerate step == 4 case.
if (step == 4) {
// this is a fairly straightforward implementation and not super-optimized.
- __m128i signflip = _mm_set1_epi8((char)0x80);
+ __m128i signflip = _mm_set1_epi8(-0x80);
__m128i cr_const0 = _mm_set1_epi16( (short) ( 1.40200f*4096.0f+0.5f));
__m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f));
__m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f));
@@ -3374,7 +3403,17 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
if (n >= 3) {
stbi_uc *y = coutput[0];
if (z->s->img_n == 3) {
- z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
+ if (z->rgb == 3) {
+ for (i=0; i < z->s->img_x; ++i) {
+ out[0] = y[i];
+ out[1] = coutput[1][i];
+ out[2] = coutput[2][i];
+ out[3] = 255;
+ out += n;
+ }
+ } else {
+ z->YCbCr_to_RGB_kernel(out, y, coutput[1], coutput[2], z->s->img_x, n);
+ }
} else
for (i=0; i < z->s->img_x; ++i) {
out[0] = out[1] = out[2] = y[i];
@@ -3399,10 +3438,13 @@ static stbi_uc *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y, int *comp
static unsigned char *stbi__jpeg_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
{
- stbi__jpeg j;
- j.s = s;
- stbi__setup_jpeg(&j);
- return load_jpeg_image(&j, x,y,comp,req_comp);
+ unsigned char* result;
+ stbi__jpeg* j = (stbi__jpeg*) stbi__malloc(sizeof(stbi__jpeg));
+ j->s = s;
+ stbi__setup_jpeg(j);
+ result = load_jpeg_image(j, x,y,comp,req_comp);
+ STBI_FREE(j);
+ return result;
}
static int stbi__jpeg_test(stbi__context *s)
@@ -3430,9 +3472,12 @@ static int stbi__jpeg_info_raw(stbi__jpeg *j, int *x, int *y, int *comp)
static int stbi__jpeg_info(stbi__context *s, int *x, int *y, int *comp)
{
- stbi__jpeg j;
- j.s = s;
- return stbi__jpeg_info_raw(&j, x, y, comp);
+ int result;
+ stbi__jpeg* j = (stbi__jpeg*) (stbi__malloc(sizeof(stbi__jpeg)));
+ j->s = s;
+ result = stbi__jpeg_info_raw(j, x, y, comp);
+ STBI_FREE(j);
+ return result;
}
#endif
@@ -3513,10 +3558,10 @@ static int stbi__zbuild_huffman(stbi__zhuffman *z, stbi_uc *sizelist, int num)
z->size [c] = (stbi_uc ) s;
z->value[c] = (stbi__uint16) i;
if (s <= STBI__ZFAST_BITS) {
- int k = stbi__bit_reverse(next_code[s],s);
- while (k < (1 << STBI__ZFAST_BITS)) {
- z->fast[k] = fastv;
- k += (1 << s);
+ int j = stbi__bit_reverse(next_code[s],s);
+ while (j < (1 << STBI__ZFAST_BITS)) {
+ z->fast[j] = fastv;
+ j += (1 << s);
}
}
++next_code[s];
@@ -3555,7 +3600,7 @@ static void stbi__fill_bits(stbi__zbuf *z)
{
do {
STBI_ASSERT(z->code_buffer < (1U << z->num_bits));
- z->code_buffer |= stbi__zget8(z) << z->num_bits;
+ z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits;
z->num_bits += 8;
} while (z->num_bits <= 24);
}
@@ -3605,14 +3650,15 @@ stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes
{
char *q;
- int cur, limit;
+ int cur, limit, old_limit;
z->zout = zout;
if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG");
cur = (int) (z->zout - z->zout_start);
- limit = (int) (z->zout_end - z->zout_start);
+ limit = old_limit = (int) (z->zout_end - z->zout_start);
while (cur + n > limit)
limit *= 2;
- q = (char *) STBI_REALLOC(z->zout_start, limit);
+ q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit);
+ STBI_NOTUSED(old_limit);
if (q == NULL) return stbi__err("outofmem", "Out of memory");
z->zout_start = q;
z->zout = q + cur;
@@ -3722,7 +3768,7 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a)
return 1;
}
-static int stbi__parse_uncomperssed_block(stbi__zbuf *a)
+static int stbi__parse_uncompressed_block(stbi__zbuf *a)
{
stbi_uc header[4];
int len,nlen,k;
@@ -3788,7 +3834,7 @@ static int stbi__parse_zlib(stbi__zbuf *a, int parse_header)
final = stbi__zreceive(a,1);
type = stbi__zreceive(a,2);
if (type == 0) {
- if (!stbi__parse_uncomperssed_block(a)) return 0;
+ if (!stbi__parse_uncompressed_block(a)) return 0;
} else if (type == 3) {
return 0;
} else {
@@ -3930,6 +3976,7 @@ typedef struct
{
stbi__context *s;
stbi_uc *idata, *expanded, *out;
+ int depth;
} stbi__png;
@@ -3969,14 +4016,19 @@ static stbi_uc stbi__depth_scale_table[9] = { 0, 0xff, 0x55, 0, 0x11, 0,0,0, 0x0
// create the png data from post-deflated data
static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 raw_len, int out_n, stbi__uint32 x, stbi__uint32 y, int depth, int color)
{
+ int bytes = (depth == 16? 2 : 1);
stbi__context *s = a->s;
- stbi__uint32 i,j,stride = x*out_n;
+ stbi__uint32 i,j,stride = x*out_n*bytes;
stbi__uint32 img_len, img_width_bytes;
int k;
int img_n = s->img_n; // copy it into a local for later
+ int output_bytes = out_n*bytes;
+ int filter_bytes = img_n*bytes;
+ int width = x;
+
STBI_ASSERT(out_n == s->img_n || out_n == s->img_n+1);
- a->out = (stbi_uc *) stbi__malloc(x * y * out_n); // extra bytes to write off the end into
+ a->out = (stbi_uc *) stbi__malloc(x * y * output_bytes); // extra bytes to write off the end into
if (!a->out) return stbi__err("outofmem", "Out of memory");
img_width_bytes = (((img_n * x * depth) + 7) >> 3);
@@ -3991,8 +4043,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
stbi_uc *cur = a->out + stride*j;
stbi_uc *prior = cur - stride;
int filter = *raw++;
- int filter_bytes = img_n;
- int width = x;
+
if (filter > 4)
return stbi__err("invalid filter","Corrupt PNG");
@@ -4025,6 +4076,14 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
raw += img_n;
cur += out_n;
prior += out_n;
+ } else if (depth == 16) {
+ if (img_n != out_n) {
+ cur[filter_bytes] = 255; // first pixel top byte
+ cur[filter_bytes+1] = 255; // first pixel bottom byte
+ }
+ raw += filter_bytes;
+ cur += output_bytes;
+ prior += output_bytes;
} else {
raw += 1;
cur += 1;
@@ -4033,7 +4092,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
// this is a little gross, so that we don't switch per-pixel or per-component
if (depth < 8 || img_n == out_n) {
- int nk = (width - 1)*img_n;
+ int nk = (width - 1)*filter_bytes;
#define CASE(f) \
case f: \
for (k=0; k < nk; ++k)
@@ -4053,18 +4112,27 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
STBI_ASSERT(img_n+1 == out_n);
#define CASE(f) \
case f: \
- for (i=x-1; i >= 1; --i, cur[img_n]=255,raw+=img_n,cur+=out_n,prior+=out_n) \
- for (k=0; k < img_n; ++k)
+ for (i=x-1; i >= 1; --i, cur[filter_bytes]=255,raw+=filter_bytes,cur+=output_bytes,prior+=output_bytes) \
+ for (k=0; k < filter_bytes; ++k)
switch (filter) {
CASE(STBI__F_none) cur[k] = raw[k]; break;
- CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k-out_n]); break;
+ CASE(STBI__F_sub) cur[k] = STBI__BYTECAST(raw[k] + cur[k- output_bytes]); break;
CASE(STBI__F_up) cur[k] = STBI__BYTECAST(raw[k] + prior[k]); break;
- CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k-out_n])>>1)); break;
- CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-out_n],prior[k],prior[k-out_n])); break;
- CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k-out_n] >> 1)); break;
- CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k-out_n],0,0)); break;
+ CASE(STBI__F_avg) cur[k] = STBI__BYTECAST(raw[k] + ((prior[k] + cur[k- output_bytes])>>1)); break;
+ CASE(STBI__F_paeth) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],prior[k],prior[k- output_bytes])); break;
+ CASE(STBI__F_avg_first) cur[k] = STBI__BYTECAST(raw[k] + (cur[k- output_bytes] >> 1)); break;
+ CASE(STBI__F_paeth_first) cur[k] = STBI__BYTECAST(raw[k] + stbi__paeth(cur[k- output_bytes],0,0)); break;
}
#undef CASE
+
+ // the loop above sets the high byte of the pixels' alpha, but for
+ // 16 bit png files we also need the low byte set. we'll do that here.
+ if (depth == 16) {
+ cur = a->out + stride*j; // start at the beginning of the row again
+ for (i=0; i < x; ++i,cur+=output_bytes) {
+ cur[filter_bytes+1] = 255;
+ }
+ }
}
}
@@ -4121,25 +4189,36 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
if (k > 6) *cur++ = scale * ((*in >> 1) & 0x01);
}
if (img_n != out_n) {
+ int q;
// insert alpha = 255
- stbi_uc *cur = a->out + stride*j;
- int i;
+ cur = a->out + stride*j;
if (img_n == 1) {
- for (i=x-1; i >= 0; --i) {
- cur[i*2+1] = 255;
- cur[i*2+0] = cur[i];
+ for (q=x-1; q >= 0; --q) {
+ cur[q*2+1] = 255;
+ cur[q*2+0] = cur[q];
}
} else {
STBI_ASSERT(img_n == 3);
- for (i=x-1; i >= 0; --i) {
- cur[i*4+3] = 255;
- cur[i*4+2] = cur[i*3+2];
- cur[i*4+1] = cur[i*3+1];
- cur[i*4+0] = cur[i*3+0];
+ for (q=x-1; q >= 0; --q) {
+ cur[q*4+3] = 255;
+ cur[q*4+2] = cur[q*3+2];
+ cur[q*4+1] = cur[q*3+1];
+ cur[q*4+0] = cur[q*3+0];
}
}
}
}
+ } else if (depth == 16) {
+ // force the image data from big-endian to platform-native.
+ // this is done in a separate pass due to the decoding relying
+ // on the data being untouched, but could probably be done
+ // per-line during decode if care is taken.
+ stbi_uc *cur = a->out;
+ stbi__uint16 *cur16 = (stbi__uint16*)cur;
+
+ for(i=0; i < x*y*out_n; ++i,cur16++,cur+=2) {
+ *cur16 = (cur[0] << 8) | cur[1];
+ }
}
return 1;
@@ -4212,6 +4291,31 @@ static int stbi__compute_transparency(stbi__png *z, stbi_uc tc[3], int out_n)
return 1;
}
+static int stbi__compute_transparency16(stbi__png *z, stbi__uint16 tc[3], int out_n)
+{
+ stbi__context *s = z->s;
+ stbi__uint32 i, pixel_count = s->img_x * s->img_y;
+ stbi__uint16 *p = (stbi__uint16*) z->out;
+
+ // compute color-based transparency, assuming we've
+ // already got 65535 as the alpha value in the output
+ STBI_ASSERT(out_n == 2 || out_n == 4);
+
+ if (out_n == 2) {
+ for (i = 0; i < pixel_count; ++i) {
+ p[1] = (p[0] == tc[0] ? 0 : 65535);
+ p += 2;
+ }
+ } else {
+ for (i = 0; i < pixel_count; ++i) {
+ if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2])
+ p[3] = 0;
+ p += 4;
+ }
+ }
+ return 1;
+}
+
static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int pal_img_n)
{
stbi__uint32 i, pixel_count = a->s->img_x * a->s->img_y;
@@ -4249,6 +4353,26 @@ static int stbi__expand_png_palette(stbi__png *a, stbi_uc *palette, int len, int
return 1;
}
+static int stbi__reduce_png(stbi__png *p)
+{
+ int i;
+ int img_len = p->s->img_x * p->s->img_y * p->s->img_out_n;
+ stbi_uc *reduced;
+ stbi__uint16 *orig = (stbi__uint16*)p->out;
+
+ if (p->depth != 16) return 1; // don't need to do anything if not 16-bit data
+
+ reduced = (stbi_uc *)stbi__malloc(img_len);
+ if (p == NULL) return stbi__err("outofmem", "Out of memory");
+
+ for (i = 0; i < img_len; ++i) reduced[i] = (stbi_uc)((orig[i] >> 8) & 0xFF); // top half of each byte is a decent approx of 16->8 bit scaling
+
+ p->out = reduced;
+ STBI_FREE(orig);
+
+ return 1;
+}
+
static int stbi__unpremultiply_on_load = 0;
static int stbi__de_iphone_flag = 0;
@@ -4310,8 +4434,9 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
{
stbi_uc palette[1024], pal_img_n=0;
stbi_uc has_trans=0, tc[3];
+ stbi__uint16 tc16[3];
stbi__uint32 ioff=0, idata_limit=0, i, pal_len=0;
- int first=1,k,interlace=0, color=0, depth=0, is_iphone=0;
+ int first=1,k,interlace=0, color=0, is_iphone=0;
stbi__context *s = z->s;
z->expanded = NULL;
@@ -4336,8 +4461,9 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG");
s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
- depth = stbi__get8(s); if (depth != 1 && depth != 2 && depth != 4 && depth != 8) return stbi__err("1/2/4/8-bit only","PNG not supported: 1/2/4/8-bit only");
+ z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only");
color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG");
+ if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG");
if (color == 3) pal_img_n = 3; else if (color & 1) return stbi__err("bad ctype","Corrupt PNG");
comp = stbi__get8(s); if (comp) return stbi__err("bad comp method","Corrupt PNG");
filter= stbi__get8(s); if (filter) return stbi__err("bad filter method","Corrupt PNG");
@@ -4385,8 +4511,11 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
if (!(s->img_n & 1)) return stbi__err("tRNS with alpha","Corrupt PNG");
if (c.length != (stbi__uint32) s->img_n*2) return stbi__err("bad tRNS len","Corrupt PNG");
has_trans = 1;
- for (k=0; k < s->img_n; ++k)
- tc[k] = (stbi_uc) (stbi__get16be(s) & 255) * stbi__depth_scale_table[depth]; // non 8-bit images will be larger
+ if (z->depth == 16) {
+ for (k = 0; k < s->img_n; ++k) tc16[k] = stbi__get16be(s); // copy the values as-is
+ } else {
+ for (k = 0; k < s->img_n; ++k) tc[k] = (stbi_uc)(stbi__get16be(s) & 255) * stbi__depth_scale_table[z->depth]; // non 8-bit images will be larger
+ }
}
break;
}
@@ -4397,11 +4526,13 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; }
if ((int)(ioff + c.length) < (int)ioff) return 0;
if (ioff + c.length > idata_limit) {
+ stbi__uint32 idata_limit_old = idata_limit;
stbi_uc *p;
if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096;
while (ioff + c.length > idata_limit)
idata_limit *= 2;
- p = (stbi_uc *) STBI_REALLOC(z->idata, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory");
+ STBI_NOTUSED(idata_limit_old);
+ p = (stbi_uc *) STBI_REALLOC_SIZED(z->idata, idata_limit_old, idata_limit); if (p == NULL) return stbi__err("outofmem", "Out of memory");
z->idata = p;
}
if (!stbi__getn(s, z->idata+ioff,c.length)) return stbi__err("outofdata","Corrupt PNG");
@@ -4415,7 +4546,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
if (scan != STBI__SCAN_load) return 1;
if (z->idata == NULL) return stbi__err("no IDAT","Corrupt PNG");
// initial guess for decoded data size to avoid unnecessary reallocs
- bpl = (s->img_x * depth + 7) / 8; // bytes per line, per component
+ bpl = (s->img_x * z->depth + 7) / 8; // bytes per line, per component
raw_len = bpl * s->img_y * s->img_n /* pixels */ + s->img_y /* filter mode per row */;
z->expanded = (stbi_uc *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, raw_len, (int *) &raw_len, !is_iphone);
if (z->expanded == NULL) return 0; // zlib should set error
@@ -4424,9 +4555,14 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
s->img_out_n = s->img_n+1;
else
s->img_out_n = s->img_n;
- if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, depth, color, interlace)) return 0;
- if (has_trans)
- if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0;
+ if (!stbi__create_png_image(z, z->expanded, raw_len, s->img_out_n, z->depth, color, interlace)) return 0;
+ if (has_trans) {
+ if (z->depth == 16) {
+ if (!stbi__compute_transparency16(z, tc16, s->img_out_n)) return 0;
+ } else {
+ if (!stbi__compute_transparency(z, tc, s->img_out_n)) return 0;
+ }
+ }
if (is_iphone && stbi__de_iphone_flag && s->img_out_n > 2)
stbi__de_iphone(z);
if (pal_img_n) {
@@ -4468,6 +4604,11 @@ static unsigned char *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req
unsigned char *result=NULL;
if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error");
if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) {
+ if (p->depth == 16) {
+ if (!stbi__reduce_png(p)) {
+ return result;
+ }
+ }
result = p->out;
p->out = NULL;
if (req_comp && req_comp != p->s->img_out_n) {
@@ -4477,7 +4618,7 @@ static unsigned char *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req
}
*x = p->s->img_x;
*y = p->s->img_y;
- if (n) *n = p->s->img_out_n;
+ if (n) *n = p->s->img_n;
}
STBI_FREE(p->out); p->out = NULL;
STBI_FREE(p->expanded); p->expanded = NULL;
@@ -4587,19 +4728,23 @@ static int stbi__shiftsigned(int v, int shift, int bits)
return result;
}
-static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
+typedef struct
{
- stbi_uc *out;
- unsigned int mr=0,mg=0,mb=0,ma=0, fake_a=0;
- stbi_uc pal[256][4];
- int psize=0,i,j,compress=0,width;
- int bpp, flip_vertically, pad, target, offset, hsz;
+ int bpp, offset, hsz;
+ unsigned int mr,mg,mb,ma, all_a;
+} stbi__bmp_data;
+
+static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
+{
+ int hsz;
if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') return stbi__errpuc("not BMP", "Corrupt BMP");
stbi__get32le(s); // discard filesize
stbi__get16le(s); // discard reserved
stbi__get16le(s); // discard reserved
- offset = stbi__get32le(s);
- hsz = stbi__get32le(s);
+ info->offset = stbi__get32le(s);
+ info->hsz = hsz = stbi__get32le(s);
+ info->mr = info->mg = info->mb = info->ma = 0;
+
if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown");
if (hsz == 12) {
s->img_x = stbi__get16le(s);
@@ -4609,15 +4754,10 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
s->img_y = stbi__get32le(s);
}
if (stbi__get16le(s) != 1) return stbi__errpuc("bad BMP", "bad BMP");
- bpp = stbi__get16le(s);
- if (bpp == 1) return stbi__errpuc("monochrome", "BMP type not supported: 1-bit");
- flip_vertically = ((int) s->img_y) > 0;
- s->img_y = abs((int) s->img_y);
- if (hsz == 12) {
- if (bpp < 24)
- psize = (offset - 14 - 24) / 3;
- } else {
- compress = stbi__get32le(s);
+ info->bpp = stbi__get16le(s);
+ if (info->bpp == 1) return stbi__errpuc("monochrome", "BMP type not supported: 1-bit");
+ if (hsz != 12) {
+ int compress = stbi__get32le(s);
if (compress == 1 || compress == 2) return stbi__errpuc("BMP RLE", "BMP type not supported: RLE");
stbi__get32le(s); // discard sizeof
stbi__get32le(s); // discard hres
@@ -4631,27 +4771,25 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
stbi__get32le(s);
stbi__get32le(s);
}
- if (bpp == 16 || bpp == 32) {
- mr = mg = mb = 0;
+ if (info->bpp == 16 || info->bpp == 32) {
if (compress == 0) {
- if (bpp == 32) {
- mr = 0xffu << 16;
- mg = 0xffu << 8;
- mb = 0xffu << 0;
- ma = 0xffu << 24;
- fake_a = 1; // @TODO: check for cases like alpha value is all 0 and switch it to 255
- STBI_NOTUSED(fake_a);
+ if (info->bpp == 32) {
+ info->mr = 0xffu << 16;
+ info->mg = 0xffu << 8;
+ info->mb = 0xffu << 0;
+ info->ma = 0xffu << 24;
+ info->all_a = 0; // if all_a is 0 at end, then we loaded alpha channel but it was all 0
} else {
- mr = 31u << 10;
- mg = 31u << 5;
- mb = 31u << 0;
+ info->mr = 31u << 10;
+ info->mg = 31u << 5;
+ info->mb = 31u << 0;
}
} else if (compress == 3) {
- mr = stbi__get32le(s);
- mg = stbi__get32le(s);
- mb = stbi__get32le(s);
+ info->mr = stbi__get32le(s);
+ info->mg = stbi__get32le(s);
+ info->mb = stbi__get32le(s);
// not documented, but generated by photoshop and handled by mspaint
- if (mr == mg && mg == mb) {
+ if (info->mr == info->mg && info->mg == info->mb) {
// ?!?!?
return stbi__errpuc("bad BMP", "bad BMP");
}
@@ -4659,11 +4797,13 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
return stbi__errpuc("bad BMP", "bad BMP");
}
} else {
- STBI_ASSERT(hsz == 108 || hsz == 124);
- mr = stbi__get32le(s);
- mg = stbi__get32le(s);
- mb = stbi__get32le(s);
- ma = stbi__get32le(s);
+ int i;
+ if (hsz != 108 && hsz != 124)
+ return stbi__errpuc("bad BMP", "bad BMP");
+ info->mr = stbi__get32le(s);
+ info->mg = stbi__get32le(s);
+ info->mb = stbi__get32le(s);
+ info->ma = stbi__get32le(s);
stbi__get32le(s); // discard color space
for (i=0; i < 12; ++i)
stbi__get32le(s); // discard color space parameters
@@ -4674,35 +4814,68 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
stbi__get32le(s); // discard reserved
}
}
- if (bpp < 16)
- psize = (offset - 14 - hsz) >> 2;
}
+ return (void *) 1;
+}
+
+
+static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
+{
+ stbi_uc *out;
+ unsigned int mr=0,mg=0,mb=0,ma=0, all_a;
+ stbi_uc pal[256][4];
+ int psize=0,i,j,width;
+ int flip_vertically, pad, target;
+ stbi__bmp_data info;
+
+ info.all_a = 255;
+ if (stbi__bmp_parse_header(s, &info) == NULL)
+ return NULL; // error code already set
+
+ flip_vertically = ((int) s->img_y) > 0;
+ s->img_y = abs((int) s->img_y);
+
+ mr = info.mr;
+ mg = info.mg;
+ mb = info.mb;
+ ma = info.ma;
+ all_a = info.all_a;
+
+ if (info.hsz == 12) {
+ if (info.bpp < 24)
+ psize = (info.offset - 14 - 24) / 3;
+ } else {
+ if (info.bpp < 16)
+ psize = (info.offset - 14 - info.hsz) >> 2;
+ }
+
s->img_n = ma ? 4 : 3;
if (req_comp && req_comp >= 3) // we can directly decode 3 or 4
target = req_comp;
else
target = s->img_n; // if they want monochrome, we'll post-convert
+
out = (stbi_uc *) stbi__malloc(target * s->img_x * s->img_y);
if (!out) return stbi__errpuc("outofmem", "Out of memory");
- if (bpp < 16) {
+ if (info.bpp < 16) {
int z=0;
if (psize == 0 || psize > 256) { STBI_FREE(out); return stbi__errpuc("invalid", "Corrupt BMP"); }
for (i=0; i < psize; ++i) {
pal[i][2] = stbi__get8(s);
pal[i][1] = stbi__get8(s);
pal[i][0] = stbi__get8(s);
- if (hsz != 12) stbi__get8(s);
+ if (info.hsz != 12) stbi__get8(s);
pal[i][3] = 255;
}
- stbi__skip(s, offset - 14 - hsz - psize * (hsz == 12 ? 3 : 4));
- if (bpp == 4) width = (s->img_x + 1) >> 1;
- else if (bpp == 8) width = s->img_x;
+ stbi__skip(s, info.offset - 14 - info.hsz - psize * (info.hsz == 12 ? 3 : 4));
+ if (info.bpp == 4) width = (s->img_x + 1) >> 1;
+ else if (info.bpp == 8) width = s->img_x;
else { STBI_FREE(out); return stbi__errpuc("bad bpp", "Corrupt BMP"); }
pad = (-width)&3;
for (j=0; j < (int) s->img_y; ++j) {
for (i=0; i < (int) s->img_x; i += 2) {
int v=stbi__get8(s),v2=0;
- if (bpp == 4) {
+ if (info.bpp == 4) {
v2 = v & 15;
v >>= 4;
}
@@ -4711,7 +4884,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
out[z++] = pal[v][2];
if (target == 4) out[z++] = 255;
if (i+1 == (int) s->img_x) break;
- v = (bpp == 8) ? stbi__get8(s) : v2;
+ v = (info.bpp == 8) ? stbi__get8(s) : v2;
out[z++] = pal[v][0];
out[z++] = pal[v][1];
out[z++] = pal[v][2];
@@ -4723,14 +4896,14 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0;
int z = 0;
int easy=0;
- stbi__skip(s, offset - 14 - hsz);
- if (bpp == 24) width = 3 * s->img_x;
- else if (bpp == 16) width = 2*s->img_x;
+ stbi__skip(s, info.offset - 14 - info.hsz);
+ if (info.bpp == 24) width = 3 * s->img_x;
+ else if (info.bpp == 16) width = 2*s->img_x;
else /* bpp = 32 and pad = 0 */ width=0;
pad = (-width) & 3;
- if (bpp == 24) {
+ if (info.bpp == 24) {
easy = 1;
- } else if (bpp == 32) {
+ } else if (info.bpp == 32) {
if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000)
easy = 2;
}
@@ -4751,9 +4924,11 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
out[z+0] = stbi__get8(s);
z += 3;
a = (easy == 2 ? stbi__get8(s) : 255);
+ all_a |= a;
if (target == 4) out[z++] = a;
}
} else {
+ int bpp = info.bpp;
for (i=0; i < (int) s->img_x; ++i) {
stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s));
int a;
@@ -4761,12 +4936,19 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount));
out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mb, bshift, bcount));
a = (ma ? stbi__shiftsigned(v & ma, ashift, acount) : 255);
+ all_a |= a;
if (target == 4) out[z++] = STBI__BYTECAST(a);
}
}
stbi__skip(s, pad);
}
}
+
+ // if alpha channel is all 0s, replace with all 255s
+ if (target == 4 && all_a == 0)
+ for (i=4*s->img_x*s->img_y-1; i >= 0; i -= 4)
+ out[i] = 255;
+
if (flip_vertically) {
stbi_uc t;
for (j=0; j < (int) s->img_y>>1; ++j) {
@@ -4793,20 +4975,55 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
// Targa Truevision - TGA
// by Jonathan Dummer
#ifndef STBI_NO_TGA
+// returns STBI_rgb or whatever, 0 on error
+static int stbi__tga_get_comp(int bits_per_pixel, int is_grey, int* is_rgb16)
+{
+ // only RGB or RGBA (incl. 16bit) or grey allowed
+ if(is_rgb16) *is_rgb16 = 0;
+ switch(bits_per_pixel) {
+ case 8: return STBI_grey;
+ case 16: if(is_grey) return STBI_grey_alpha;
+ // else: fall-through
+ case 15: if(is_rgb16) *is_rgb16 = 1;
+ return STBI_rgb;
+ case 24: // fall-through
+ case 32: return bits_per_pixel/8;
+ default: return 0;
+ }
+}
+
static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp)
{
- int tga_w, tga_h, tga_comp;
- int sz;
+ int tga_w, tga_h, tga_comp, tga_image_type, tga_bits_per_pixel, tga_colormap_bpp;
+ int sz, tga_colormap_type;
stbi__get8(s); // discard Offset
- sz = stbi__get8(s); // color type
- if( sz > 1 ) {
+ tga_colormap_type = stbi__get8(s); // colormap type
+ if( tga_colormap_type > 1 ) {
stbi__rewind(s);
return 0; // only RGB or indexed allowed
}
- sz = stbi__get8(s); // image type
- // only RGB or grey allowed, +/- RLE
- if ((sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11)) return 0;
- stbi__skip(s,9);
+ tga_image_type = stbi__get8(s); // image type
+ if ( tga_colormap_type == 1 ) { // colormapped (paletted) image
+ if (tga_image_type != 1 && tga_image_type != 9) {
+ stbi__rewind(s);
+ return 0;
+ }
+ stbi__skip(s,4); // skip index of first colormap entry and number of entries
+ sz = stbi__get8(s); // check bits per palette color entry
+ if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) {
+ stbi__rewind(s);
+ return 0;
+ }
+ stbi__skip(s,4); // skip image x and y origin
+ tga_colormap_bpp = sz;
+ } else { // "normal" image w/o colormap - only RGB or grey allowed, +/- RLE
+ if ( (tga_image_type != 2) && (tga_image_type != 3) && (tga_image_type != 10) && (tga_image_type != 11) ) {
+ stbi__rewind(s);
+ return 0; // only RGB or grey allowed, +/- RLE
+ }
+ stbi__skip(s,9); // skip colormap specification and image x/y origin
+ tga_colormap_bpp = 0;
+ }
tga_w = stbi__get16le(s);
if( tga_w < 1 ) {
stbi__rewind(s);
@@ -4817,44 +5034,80 @@ static int stbi__tga_info(stbi__context *s, int *x, int *y, int *comp)
stbi__rewind(s);
return 0; // test height
}
- sz = stbi__get8(s); // bits per pixel
- // only RGB or RGBA or grey allowed
- if ((sz != 8) && (sz != 16) && (sz != 24) && (sz != 32)) {
- stbi__rewind(s);
- return 0;
+ tga_bits_per_pixel = stbi__get8(s); // bits per pixel
+ stbi__get8(s); // ignore alpha bits
+ if (tga_colormap_bpp != 0) {
+ if((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16)) {
+ // when using a colormap, tga_bits_per_pixel is the size of the indexes
+ // I don't think anything but 8 or 16bit indexes makes sense
+ stbi__rewind(s);
+ return 0;
+ }
+ tga_comp = stbi__tga_get_comp(tga_colormap_bpp, 0, NULL);
+ } else {
+ tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3) || (tga_image_type == 11), NULL);
+ }
+ if(!tga_comp) {
+ stbi__rewind(s);
+ return 0;
}
- tga_comp = sz;
if (x) *x = tga_w;
if (y) *y = tga_h;
- if (comp) *comp = tga_comp / 8;
+ if (comp) *comp = tga_comp;
return 1; // seems to have passed everything
}
static int stbi__tga_test(stbi__context *s)
{
- int res;
- int sz;
+ int res = 0;
+ int sz, tga_color_type;
stbi__get8(s); // discard Offset
- sz = stbi__get8(s); // color type
- if ( sz > 1 ) return 0; // only RGB or indexed allowed
+ tga_color_type = stbi__get8(s); // color type
+ if ( tga_color_type > 1 ) goto errorEnd; // only RGB or indexed allowed
sz = stbi__get8(s); // image type
- if ( (sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11) ) return 0; // only RGB or grey allowed, +/- RLE
- stbi__get16be(s); // discard palette start
- stbi__get16be(s); // discard palette length
- stbi__get8(s); // discard bits per palette color entry
- stbi__get16be(s); // discard x origin
- stbi__get16be(s); // discard y origin
- if ( stbi__get16be(s) < 1 ) return 0; // test width
- if ( stbi__get16be(s) < 1 ) return 0; // test height
+ if ( tga_color_type == 1 ) { // colormapped (paletted) image
+ if (sz != 1 && sz != 9) goto errorEnd; // colortype 1 demands image type 1 or 9
+ stbi__skip(s,4); // skip index of first colormap entry and number of entries
+ sz = stbi__get8(s); // check bits per palette color entry
+ if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd;
+ stbi__skip(s,4); // skip image x and y origin
+ } else { // "normal" image w/o colormap
+ if ( (sz != 2) && (sz != 3) && (sz != 10) && (sz != 11) ) goto errorEnd; // only RGB or grey allowed, +/- RLE
+ stbi__skip(s,9); // skip colormap specification and image x/y origin
+ }
+ if ( stbi__get16le(s) < 1 ) goto errorEnd; // test width
+ if ( stbi__get16le(s) < 1 ) goto errorEnd; // test height
sz = stbi__get8(s); // bits per pixel
- if ( (sz != 8) && (sz != 16) && (sz != 24) && (sz != 32) )
- res = 0;
- else
- res = 1;
+ if ( (tga_color_type == 1) && (sz != 8) && (sz != 16) ) goto errorEnd; // for colormapped images, bpp is size of an index
+ if ( (sz != 8) && (sz != 15) && (sz != 16) && (sz != 24) && (sz != 32) ) goto errorEnd;
+
+ res = 1; // if we got this far, everything's good and we can return 1 instead of 0
+
+errorEnd:
stbi__rewind(s);
return res;
}
+// read 16bit value and convert to 24bit RGB
+void stbi__tga_read_rgb16(stbi__context *s, stbi_uc* out)
+{
+ stbi__uint16 px = stbi__get16le(s);
+ stbi__uint16 fiveBitMask = 31;
+ // we have 3 channels with 5bits each
+ int r = (px >> 10) & fiveBitMask;
+ int g = (px >> 5) & fiveBitMask;
+ int b = px & fiveBitMask;
+ // Note that this saves the data in RGB(A) order, so it doesn't need to be swapped later
+ out[0] = (r * 255)/31;
+ out[1] = (g * 255)/31;
+ out[2] = (b * 255)/31;
+
+ // some people claim that the most significant bit might be used for alpha
+ // (possibly if an alpha-bit is set in the "image descriptor byte")
+ // but that only made 16bit test images completely translucent..
+ // so let's treat all 15 and 16bit TGAs as RGB with no alpha.
+}
+
static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
{
// read in the TGA header stuff
@@ -4870,8 +5123,9 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
int tga_width = stbi__get16le(s);
int tga_height = stbi__get16le(s);
int tga_bits_per_pixel = stbi__get8(s);
- int tga_comp = tga_bits_per_pixel / 8;
+ int tga_comp, tga_rgb16=0;
int tga_inverted = stbi__get8(s);
+ // int tga_alpha_bits = tga_inverted & 15; // the 4 lowest bits - unused (useless?)
// image data
unsigned char *tga_data;
unsigned char *tga_palette = NULL;
@@ -4887,25 +5141,14 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
tga_image_type -= 8;
tga_is_RLE = 1;
}
- /* int tga_alpha_bits = tga_inverted & 15; */
tga_inverted = 1 - ((tga_inverted >> 5) & 1);
- // error check
- if ( //(tga_indexed) ||
- (tga_width < 1) || (tga_height < 1) ||
- (tga_image_type < 1) || (tga_image_type > 3) ||
- ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16) &&
- (tga_bits_per_pixel != 24) && (tga_bits_per_pixel != 32))
- )
- {
- return NULL; // we don't report this as a bad TGA because we don't even know if it's TGA
- }
-
// If I'm paletted, then I'll use the number of bits from the palette
- if ( tga_indexed )
- {
- tga_comp = tga_palette_bits / 8;
- }
+ if ( tga_indexed ) tga_comp = stbi__tga_get_comp(tga_palette_bits, 0, &tga_rgb16);
+ else tga_comp = stbi__tga_get_comp(tga_bits_per_pixel, (tga_image_type == 3), &tga_rgb16);
+
+ if(!tga_comp) // shouldn't really happen, stbi__tga_test() should have ensured basic consistency
+ return stbi__errpuc("bad format", "Can't find out TGA pixelformat");
// tga info
*x = tga_width;
@@ -4918,10 +5161,10 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
// skip to the data's starting position (offset usually = 0)
stbi__skip(s, tga_offset );
- if ( !tga_indexed && !tga_is_RLE) {
+ if ( !tga_indexed && !tga_is_RLE && !tga_rgb16 ) {
for (i=0; i < tga_height; ++i) {
- int y = tga_inverted ? tga_height -i - 1 : i;
- stbi_uc *tga_row = tga_data + y*tga_width*tga_comp;
+ int row = tga_inverted ? tga_height -i - 1 : i;
+ stbi_uc *tga_row = tga_data + row*tga_width*tga_comp;
stbi__getn(s, tga_row, tga_width * tga_comp);
}
} else {
@@ -4931,15 +5174,22 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
// any data to skip? (offset usually = 0)
stbi__skip(s, tga_palette_start );
// load the palette
- tga_palette = (unsigned char*)stbi__malloc( tga_palette_len * tga_palette_bits / 8 );
+ tga_palette = (unsigned char*)stbi__malloc( tga_palette_len * tga_comp );
if (!tga_palette) {
STBI_FREE(tga_data);
return stbi__errpuc("outofmem", "Out of memory");
}
- if (!stbi__getn(s, tga_palette, tga_palette_len * tga_palette_bits / 8 )) {
- STBI_FREE(tga_data);
- STBI_FREE(tga_palette);
- return stbi__errpuc("bad palette", "Corrupt TGA");
+ if (tga_rgb16) {
+ stbi_uc *pal_entry = tga_palette;
+ STBI_ASSERT(tga_comp == STBI_rgb);
+ for (i=0; i < tga_palette_len; ++i) {
+ stbi__tga_read_rgb16(s, pal_entry);
+ pal_entry += tga_comp;
+ }
+ } else if (!stbi__getn(s, tga_palette, tga_palette_len * tga_comp)) {
+ STBI_FREE(tga_data);
+ STBI_FREE(tga_palette);
+ return stbi__errpuc("bad palette", "Corrupt TGA");
}
}
// load the data
@@ -4969,23 +5219,22 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
// load however much data we did have
if ( tga_indexed )
{
- // read in 1 byte, then perform the lookup
- int pal_idx = stbi__get8(s);
- if ( pal_idx >= tga_palette_len )
- {
- // invalid index
+ // read in index, then perform the lookup
+ int pal_idx = (tga_bits_per_pixel == 8) ? stbi__get8(s) : stbi__get16le(s);
+ if ( pal_idx >= tga_palette_len ) {
+ // invalid index
pal_idx = 0;
}
- pal_idx *= tga_bits_per_pixel / 8;
- for (j = 0; j*8 < tga_bits_per_pixel; ++j)
- {
+ pal_idx *= tga_comp;
+ for (j = 0; j < tga_comp; ++j) {
raw_data[j] = tga_palette[pal_idx+j];
}
- } else
- {
+ } else if(tga_rgb16) {
+ STBI_ASSERT(tga_comp == STBI_rgb);
+ stbi__tga_read_rgb16(s, raw_data);
+ } else {
// read in the data raw
- for (j = 0; j*8 < tga_bits_per_pixel; ++j)
- {
+ for (j = 0; j < tga_comp; ++j) {
raw_data[j] = stbi__get8(s);
}
}
@@ -5024,8 +5273,8 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
}
}
- // swap RGB
- if (tga_comp >= 3)
+ // swap RGB - if the source data was RGB16, it already is in the right order
+ if (tga_comp >= 3 && !tga_rgb16)
{
unsigned char* tga_pixel = tga_data;
for (i=0; i < tga_width * tga_height; ++i)
@@ -5066,6 +5315,7 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
int pixelCount;
int channelCount, compression;
int channel, i, count, len;
+ int bitdepth;
int w,h;
stbi_uc *out;
@@ -5090,8 +5340,9 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
w = stbi__get32be(s);
// Make sure the depth is 8 bits.
- if (stbi__get16be(s) != 8)
- return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 bit");
+ bitdepth = stbi__get16be(s);
+ if (bitdepth != 8 && bitdepth != 16)
+ return stbi__errpuc("unsupported bit depth", "PSD bit depth is not 8 or 16 bit");
// Make sure the color mode is RGB.
// Valid options are:
@@ -5197,14 +5448,35 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
stbi_uc *p;
p = out + channel;
- if (channel > channelCount) {
+ if (channel >= channelCount) {
// Fill this channel with default data.
+ stbi_uc val = channel == 3 ? 255 : 0;
for (i = 0; i < pixelCount; i++, p += 4)
- *p = channel == 3 ? 255 : 0;
+ *p = val;
} else {
// Read the data.
- for (i = 0; i < pixelCount; i++, p += 4)
- *p = stbi__get8(s);
+ if (bitdepth == 16) {
+ for (i = 0; i < pixelCount; i++, p += 4)
+ *p = (stbi_uc) (stbi__get16be(s) >> 8);
+ } else {
+ for (i = 0; i < pixelCount; i++, p += 4)
+ *p = stbi__get8(s);
+ }
+ }
+ }
+ }
+
+ if (channelCount >= 4) {
+ for (i=0; i < w*h; ++i) {
+ unsigned char *pixel = out + 4*i;
+ if (pixel[3] != 0 && pixel[3] != 255) {
+ // remove weird white matte from PSD
+ float a = pixel[3] / 255.0f;
+ float ra = 1.0f / a;
+ float inv_a = 255.0f * (1 - ra);
+ pixel[0] = (unsigned char) (pixel[0]*ra + inv_a);
+ pixel[1] = (unsigned char) (pixel[1]*ra + inv_a);
+ pixel[2] = (unsigned char) (pixel[2]*ra + inv_a);
}
}
}
@@ -5362,7 +5634,6 @@ static stbi_uc *stbi__pic_load_core(stbi__context *s,int width,int height,int *c
if (count >= 128) { // Repeated
stbi_uc value[4];
- int i;
if (count==128)
count = stbi__get16be(s);
@@ -5450,8 +5721,8 @@ typedef struct
typedef struct
{
int w,h;
- stbi_uc *out; // output buffer (always 4 components)
- int flags, bgindex, ratio, transparent, eflags;
+ stbi_uc *out, *old_out; // output buffer (always 4 components)
+ int flags, bgindex, ratio, transparent, eflags, delay;
stbi_uc pal[256][4];
stbi_uc lpal[256][4];
stbi__gif_lzw codes[4096];
@@ -5522,13 +5793,15 @@ static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_in
static int stbi__gif_info_raw(stbi__context *s, int *x, int *y, int *comp)
{
- stbi__gif g;
- if (!stbi__gif_header(s, &g, comp, 1)) {
+ stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif));
+ if (!stbi__gif_header(s, g, comp, 1)) {
+ STBI_FREE(g);
stbi__rewind( s );
return 0;
}
- if (x) *x = g.w;
- if (y) *y = g.h;
+ if (x) *x = g->w;
+ if (y) *y = g->h;
+ STBI_FREE(g);
return 1;
}
@@ -5569,7 +5842,7 @@ static void stbi__out_gif_code(stbi__gif *g, stbi__uint16 code)
static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g)
{
stbi_uc lzw_cs;
- stbi__int32 len, code;
+ stbi__int32 len, init_code;
stbi__uint32 first;
stbi__int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear;
stbi__gif_lzw *p;
@@ -5582,10 +5855,10 @@ static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g)
codemask = (1 << codesize) - 1;
bits = 0;
valid_bits = 0;
- for (code = 0; code < clear; code++) {
- g->codes[code].prefix = -1;
- g->codes[code].first = (stbi_uc) code;
- g->codes[code].suffix = (stbi_uc) code;
+ for (init_code = 0; init_code < clear; init_code++) {
+ g->codes[init_code].prefix = -1;
+ g->codes[init_code].first = (stbi_uc) init_code;
+ g->codes[init_code].suffix = (stbi_uc) init_code;
}
// support no starting clear code
@@ -5646,17 +5919,18 @@ static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g)
}
}
-static void stbi__fill_gif_background(stbi__gif *g)
+static void stbi__fill_gif_background(stbi__gif *g, int x0, int y0, int x1, int y1)
{
- int i;
+ int x, y;
stbi_uc *c = g->pal[g->bgindex];
- // @OPTIMIZE: write a dword at a time
- for (i = 0; i < g->w * g->h * 4; i += 4) {
- stbi_uc *p = &g->out[i];
- p[0] = c[2];
- p[1] = c[1];
- p[2] = c[0];
- p[3] = c[3];
+ for (y = y0; y < y1; y += 4 * g->w) {
+ for (x = x0; x < x1; x += 4) {
+ stbi_uc *p = &g->out[y + x];
+ p[0] = c[2];
+ p[1] = c[1];
+ p[2] = c[0];
+ p[3] = 0;
+ }
}
}
@@ -5664,27 +5938,40 @@ static void stbi__fill_gif_background(stbi__gif *g)
static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, int req_comp)
{
int i;
- stbi_uc *old_out = 0;
+ stbi_uc *prev_out = 0;
- if (g->out == 0) {
- if (!stbi__gif_header(s, g, comp,0)) return 0; // stbi__g_failure_reason set by stbi__gif_header
- g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h);
- if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory");
- stbi__fill_gif_background(g);
- } else {
- // animated-gif-only path
- if (((g->eflags & 0x1C) >> 2) == 3) {
- old_out = g->out;
- g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h);
- if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory");
- memcpy(g->out, old_out, g->w*g->h*4);
- }
+ if (g->out == 0 && !stbi__gif_header(s, g, comp,0))
+ return 0; // stbi__g_failure_reason set by stbi__gif_header
+
+ prev_out = g->out;
+ g->out = (stbi_uc *) stbi__malloc(4 * g->w * g->h);
+ if (g->out == 0) return stbi__errpuc("outofmem", "Out of memory");
+
+ switch ((g->eflags & 0x1C) >> 2) {
+ case 0: // unspecified (also always used on 1st frame)
+ stbi__fill_gif_background(g, 0, 0, 4 * g->w, 4 * g->w * g->h);
+ break;
+ case 1: // do not dispose
+ if (prev_out) memcpy(g->out, prev_out, 4 * g->w * g->h);
+ g->old_out = prev_out;
+ break;
+ case 2: // dispose to background
+ if (prev_out) memcpy(g->out, prev_out, 4 * g->w * g->h);
+ stbi__fill_gif_background(g, g->start_x, g->start_y, g->max_x, g->max_y);
+ break;
+ case 3: // dispose to previous
+ if (g->old_out) {
+ for (i = g->start_y; i < g->max_y; i += 4 * g->w)
+ memcpy(&g->out[i + g->start_x], &g->old_out[i + g->start_x], g->max_x - g->start_x);
+ }
+ break;
}
for (;;) {
switch (stbi__get8(s)) {
case 0x2C: /* Image Descriptor */
{
+ int prev_trans = -1;
stbi__int32 x, y, w, h;
stbi_uc *o;
@@ -5717,10 +6004,10 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
stbi__gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1);
g->color_table = (stbi_uc *) g->lpal;
} else if (g->flags & 0x80) {
- for (i=0; i < 256; ++i) // @OPTIMIZE: stbi__jpeg_reset only the previous transparent
- g->pal[i][3] = 255;
- if (g->transparent >= 0 && (g->eflags & 0x01))
+ if (g->transparent >= 0 && (g->eflags & 0x01)) {
+ prev_trans = g->pal[g->transparent][3];
g->pal[g->transparent][3] = 0;
+ }
g->color_table = (stbi_uc *) g->pal;
} else
return stbi__errpuc("missing color table", "Corrupt GIF");
@@ -5728,8 +6015,9 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
o = stbi__process_gif_raster(s, g);
if (o == NULL) return NULL;
- if (req_comp && req_comp != 4)
- o = stbi__convert_format(o, 4, req_comp, g->w, g->h);
+ if (prev_trans != -1)
+ g->pal[g->transparent][3] = (stbi_uc) prev_trans;
+
return o;
}
@@ -5740,7 +6028,7 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
len = stbi__get8(s);
if (len == 4) {
g->eflags = stbi__get8(s);
- stbi__get16le(s); // delay
+ g->delay = stbi__get16le(s);
g->transparent = stbi__get8(s);
} else {
stbi__skip(s, len);
@@ -5759,21 +6047,27 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
return stbi__errpuc("unknown code", "Corrupt GIF");
}
}
+
+ STBI_NOTUSED(req_comp);
}
static stbi_uc *stbi__gif_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
{
stbi_uc *u = 0;
- stbi__gif g;
- memset(&g, 0, sizeof(g));
+ stbi__gif* g = (stbi__gif*) stbi__malloc(sizeof(stbi__gif));
+ memset(g, 0, sizeof(*g));
- u = stbi__gif_load_next(s, &g, comp, req_comp);
+ u = stbi__gif_load_next(s, g, comp, req_comp);
if (u == (stbi_uc *) s) u = 0; // end of animated gif marker
if (u) {
- *x = g.w;
- *y = g.h;
- }
-
+ *x = g->w;
+ *y = g->h;
+ if (req_comp && req_comp != 4)
+ u = stbi__convert_format(u, 4, req_comp, g->w, g->h);
+ }
+ else if (g->out)
+ STBI_FREE(g->out);
+ STBI_FREE(g);
return u;
}
@@ -5971,7 +6265,7 @@ static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp)
char *token;
int valid = 0;
- if (strcmp(stbi__hdr_gettoken(s,buffer), "#?RADIANCE") != 0) {
+ if (stbi__hdr_test(s) == 0) {
stbi__rewind( s );
return 0;
}
@@ -6008,29 +6302,17 @@ static int stbi__hdr_info(stbi__context *s, int *x, int *y, int *comp)
#ifndef STBI_NO_BMP
static int stbi__bmp_info(stbi__context *s, int *x, int *y, int *comp)
{
- int hsz;
- if (stbi__get8(s) != 'B' || stbi__get8(s) != 'M') {
- stbi__rewind( s );
- return 0;
- }
- stbi__skip(s,12);
- hsz = stbi__get32le(s);
- if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) {
- stbi__rewind( s );
- return 0;
- }
- if (hsz == 12) {
- *x = stbi__get16le(s);
- *y = stbi__get16le(s);
- } else {
- *x = stbi__get32le(s);
- *y = stbi__get32le(s);
- }
- if (stbi__get16le(s) != 1) {
- stbi__rewind( s );
- return 0;
- }
- *comp = stbi__get16le(s) / 8;
+ void *p;
+ stbi__bmp_data info;
+
+ info.all_a = 255;
+ p = stbi__bmp_parse_header(s, &info);
+ stbi__rewind( s );
+ if (p == NULL)
+ return 0;
+ *x = s->img_x;
+ *y = s->img_y;
+ *comp = info.ma ? 4 : 3;
return 1;
}
#endif
@@ -6074,14 +6356,22 @@ static int stbi__pic_info(stbi__context *s, int *x, int *y, int *comp)
int act_comp=0,num_packets=0,chained;
stbi__pic_packet packets[10];
- stbi__skip(s, 92);
+ if (!stbi__pic_is4(s,"\x53\x80\xF6\x34")) {
+ stbi__rewind(s);
+ return 0;
+ }
+
+ stbi__skip(s, 88);
*x = stbi__get16be(s);
*y = stbi__get16be(s);
- if (stbi__at_eof(s)) return 0;
+ if (stbi__at_eof(s)) {
+ stbi__rewind( s);
+ return 0;
+ }
if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) {
- stbi__rewind( s );
- return 0;
+ stbi__rewind( s );
+ return 0;
}
stbi__skip(s, 8);
@@ -6168,8 +6458,16 @@ static int stbi__pnm_isspace(char c)
static void stbi__pnm_skip_whitespace(stbi__context *s, char *c)
{
- while (!stbi__at_eof(s) && stbi__pnm_isspace(*c))
- *c = (char) stbi__get8(s);
+ for (;;) {
+ while (!stbi__at_eof(s) && stbi__pnm_isspace(*c))
+ *c = (char) stbi__get8(s);
+
+ if (stbi__at_eof(s) || *c != '#')
+ break;
+
+ while (!stbi__at_eof(s) && *c != '\n' && *c != '\r' )
+ *c = (char) stbi__get8(s);
+ }
}
static int stbi__pnm_isdigit(char c)
@@ -6307,6 +6605,26 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
/*
revision history:
+ 2.12 (2016-04-02) fix typo in 2.11 PSD fix that caused crashes
+ 2.11 (2016-04-02) allocate large structures on the stack
+ remove white matting for transparent PSD
+ fix reported channel count for PNG & BMP
+ re-enable SSE2 in non-gcc 64-bit
+ support RGB-formatted JPEG
+ read 16-bit PNGs (only as 8-bit)
+ 2.10 (2016-01-22) avoid warning introduced in 2.09 by STBI_REALLOC_SIZED
+ 2.09 (2016-01-16) allow comments in PNM files
+ 16-bit-per-pixel TGA (not bit-per-component)
+ info() for TGA could break due to .hdr handling
+ info() for BMP to shares code instead of sloppy parse
+ can use STBI_REALLOC_SIZED if allocator doesn't support realloc
+ code cleanup
+ 2.08 (2015-09-13) fix to 2.07 cleanup, reading RGB PSD as RGBA
+ 2.07 (2015-09-13) fix compiler warnings
+ partial animated GIF support
+ limited 16-bpc PSD support
+ #ifdef unused functions
+ bug with < 92 byte PIC,PNM,HDR,TGA
2.06 (2015-04-19) fix bug where PSD returns wrong '*comp' value
2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning
2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit
diff --git a/3rdparty/bgfx/3rdparty/stb/stb_rect_pack.h b/3rdparty/bgfx/3rdparty/stb/stb_rect_pack.h
index eb0ef2f268f..b09786bd520 100644
--- a/3rdparty/bgfx/3rdparty/stb/stb_rect_pack.h
+++ b/3rdparty/bgfx/3rdparty/stb/stb_rect_pack.h
@@ -1,4 +1,12 @@
-// stb_rect_pack.h - v0.05 - public domain - rectangle packing
+#if defined(__GNUC__) || defined(__clang__)
+# pragma GCC diagnostic ignored "-Wtype-limits"
+# pragma GCC diagnostic ignored "-Wunused-function"
+# pragma GCC diagnostic ignored "-Wunused-parameter"
+#else
+# pragma warning(disable:4100) // C4100: 'c': unreferenced formal parameter
+#endif
+
+// stb_rect_pack.h - v0.08 - public domain - rectangle packing
// Sean Barrett 2014
//
// Useful for e.g. packing rectangular textures into an atlas.
@@ -13,6 +21,7 @@
// More docs to come.
//
// No memory allocations; uses qsort() and assert() from stdlib.
+// Can override those by defining STBRP_SORT and STBRP_ASSERT.
//
// This library currently uses the Skyline Bottom-Left algorithm.
//
@@ -20,11 +29,29 @@
// implement them to the same API, but with a different init
// function.
//
+// Credits
+//
+// Library
+// Sean Barrett
+// Minor features
+// Martins Mozeiko
+// Bugfixes / warning fixes
+// Jeremy Jaussaud
+//
// Version history:
//
+// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
+// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
+// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
// 0.05: added STBRP_ASSERT to allow replacing assert
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
// 0.01: initial release
+//
+// LICENSE
+//
+// This software is dual-licensed to the public domain and under the following
+// license: you are granted a perpetual, irrevocable license to copy, modify,
+// publish, and distribute this file as you see fit.
//////////////////////////////////////////////////////////////////////////////
//
@@ -129,7 +156,7 @@ enum
{
STBRP_HEURISTIC_Skyline_default=0,
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
- STBRP_HEURISTIC_Skyline_BF_sortHeight
+ STBRP_HEURISTIC_Skyline_BF_sortHeight,
};
@@ -169,7 +196,10 @@ struct stbrp_context
//
#ifdef STB_RECT_PACK_IMPLEMENTATION
+#ifndef STBRP_SORT
#include <stdlib.h>
+#define STBRP_SORT qsort
+#endif
#ifndef STBRP_ASSERT
#include <assert.h>
@@ -178,7 +208,7 @@ struct stbrp_context
enum
{
- STBRP__INIT_skyline = 1
+ STBRP__INIT_skyline = 1,
};
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
@@ -248,7 +278,6 @@ STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height,
// 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;
@@ -525,20 +554,24 @@ STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int n
}
// sort according to heuristic
- qsort(rects, num_rects, sizeof(rects[0]), rect_height_compare);
+ STBRP_SORT(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;
+ if (rects[i].w == 0 || rects[i].h == 0) {
+ rects[i].x = rects[i].y = 0; // empty rect needs no space
} else {
- rects[i].x = rects[i].y = STBRP__MAXVAL;
+ 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);
+ STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
// set was_packed flags
for (i=0; i < num_rects; ++i)
diff --git a/3rdparty/bgfx/3rdparty/stb/stb_textedit.h b/3rdparty/bgfx/3rdparty/stb/stb_textedit.h
index 5aa79f02ada..29af484b1c6 100644
--- a/3rdparty/bgfx/3rdparty/stb/stb_textedit.h
+++ b/3rdparty/bgfx/3rdparty/stb/stb_textedit.h
@@ -1,4 +1,4 @@
-// stb_textedit.h - v1.4 - public domain - Sean Barrett
+// stb_textedit.h - v1.8 - public domain - Sean Barrett
// Development of this library was sponsored by RAD Game Tools
//
// This C header file implements the guts of a multi-line text-editing
@@ -17,19 +17,24 @@
//
// LICENSE
//
-// This software has been placed in the public domain by its author.
-// Where that dedication is not recognized, you are granted a perpetual,
-// irrevocable license to copy and modify this file as you see fit.
+// This software is dual-licensed to the public domain and under the following
+// license: you are granted a perpetual, irrevocable license to copy, modify,
+// publish, and distribute this file as you see fit.
//
//
// DEPENDENCIES
//
-// Uses the C runtime function 'memmove'. Uses no other functions.
-// Performs no runtime allocations.
+// Uses the C runtime function 'memmove', which you can override
+// by defining STB_TEXTEDIT_memmove before the implementation.
+// Uses no other functions. Performs no runtime allocations.
//
//
// VERSION HISTORY
//
+// 1.8 (2016-04-02) better keyboard handling when mouse button is down
+// 1.7 (2015-09-13) change y range handling in case baseline is non-0
+// 1.6 (2015-04-15) allow STB_TEXTEDIT_memmove
+// 1.5 (2014-09-10) add support for secondary keys for OS X
// 1.4 (2014-08-17) fix signed/unsigned warnings
// 1.3 (2014-06-19) fix mouse clicking to round to nearest char boundary
// 1.2 (2014-05-27) fix some RAD types that had crept into the new code
@@ -42,7 +47,13 @@
// ADDITIONAL CONTRIBUTORS
//
// Ulf Winklemann: move-by-word in 1.1
-// Scott Graham: mouse selection bugfix in 1.3
+// Fabian Giesen: secondary key inputs in 1.5
+// Martins Mozeiko: STB_TEXTEDIT_memmove
+//
+// Bugfixes:
+// Scott Graham
+// Daniel Keller
+// Omar Cornut
//
// USAGE
//
@@ -142,6 +153,10 @@
// required for WORDLEFT/WORDRIGHT
// STB_TEXTEDIT_K_WORDLEFT keyboard input to move cursor left one word // e.g. ctrl-LEFT
// STB_TEXTEDIT_K_WORDRIGHT keyboard input to move cursor right one word // e.g. ctrl-RIGHT
+// STB_TEXTEDIT_K_LINESTART2 secondary keyboard input to move cursor to start of line
+// STB_TEXTEDIT_K_LINEEND2 secondary keyboard input to move cursor to end of line
+// STB_TEXTEDIT_K_TEXTSTART2 secondary keyboard input to move cursor to start of text
+// STB_TEXTEDIT_K_TEXTEND2 secondary keyboard input to move cursor to end of text
//
// Todo:
// STB_TEXTEDIT_K_PGUP keyboard input to move cursor up a page
@@ -352,7 +367,10 @@ typedef struct
// included just the "header" portion
#ifdef STB_TEXTEDIT_IMPLEMENTATION
-#include <string.h> // memmove
+#ifndef STB_TEXTEDIT_memmove
+#include <string.h>
+#define STB_TEXTEDIT_memmove memmove
+#endif
/////////////////////////////////////////////////////////////////////////////
@@ -368,9 +386,6 @@ static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
float base_y = 0, prev_x;
int i=0, k;
- if (y < 0)
- return 0;
-
r.x0 = r.x1 = 0;
r.ymin = r.ymax = 0;
r.num_chars = 0;
@@ -381,6 +396,9 @@ static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
if (r.num_chars <= 0)
return n;
+ if (i==0 && y < base_y + r.ymin)
+ return 0;
+
if (y < base_y + r.ymax)
break;
@@ -434,6 +452,8 @@ static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *stat
static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
{
int p = stb_text_locate_coord(str, x, y);
+ if (state->select_start == state->select_end)
+ state->select_start = state->cursor;
state->cursor = state->select_end = p;
}
@@ -917,23 +937,35 @@ retry:
state->has_preferred_x = 0;
break;
+#ifdef STB_TEXTEDIT_K_TEXTSTART2
+ case STB_TEXTEDIT_K_TEXTSTART2:
+#endif
case STB_TEXTEDIT_K_TEXTSTART:
state->cursor = state->select_start = state->select_end = 0;
state->has_preferred_x = 0;
break;
+#ifdef STB_TEXTEDIT_K_TEXTEND2
+ case STB_TEXTEDIT_K_TEXTEND2:
+#endif
case STB_TEXTEDIT_K_TEXTEND:
state->cursor = STB_TEXTEDIT_STRINGLEN(str);
state->select_start = state->select_end = 0;
state->has_preferred_x = 0;
break;
+#ifdef STB_TEXTEDIT_K_TEXTSTART2
+ case STB_TEXTEDIT_K_TEXTSTART2 | STB_TEXTEDIT_K_SHIFT:
+#endif
case STB_TEXTEDIT_K_TEXTSTART | STB_TEXTEDIT_K_SHIFT:
stb_textedit_prep_selection_at_cursor(state);
state->cursor = state->select_end = 0;
state->has_preferred_x = 0;
break;
+#ifdef STB_TEXTEDIT_K_TEXTEND2
+ case STB_TEXTEDIT_K_TEXTEND2 | STB_TEXTEDIT_K_SHIFT:
+#endif
case STB_TEXTEDIT_K_TEXTEND | STB_TEXTEDIT_K_SHIFT:
stb_textedit_prep_selection_at_cursor(state);
state->cursor = state->select_end = STB_TEXTEDIT_STRINGLEN(str);
@@ -941,6 +973,9 @@ retry:
break;
+#ifdef STB_TEXTEDIT_K_LINESTART2
+ case STB_TEXTEDIT_K_LINESTART2:
+#endif
case STB_TEXTEDIT_K_LINESTART: {
StbFindState find;
stb_textedit_clamp(str, state);
@@ -951,16 +986,25 @@ retry:
break;
}
+#ifdef STB_TEXTEDIT_K_LINEEND2
+ case STB_TEXTEDIT_K_LINEEND2:
+#endif
case STB_TEXTEDIT_K_LINEEND: {
StbFindState find;
stb_textedit_clamp(str, state);
stb_textedit_move_to_first(state);
stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
- state->cursor = find.first_char + find.length;
+
state->has_preferred_x = 0;
+ state->cursor = find.first_char + find.length;
+ if (find.length > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) == STB_TEXTEDIT_NEWLINE)
+ --state->cursor;
break;
}
+#ifdef STB_TEXTEDIT_K_LINESTART2
+ case STB_TEXTEDIT_K_LINESTART2 | STB_TEXTEDIT_K_SHIFT:
+#endif
case STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT: {
StbFindState find;
stb_textedit_clamp(str, state);
@@ -971,13 +1015,19 @@ retry:
break;
}
+#ifdef STB_TEXTEDIT_K_LINEEND2
+ case STB_TEXTEDIT_K_LINEEND2 | STB_TEXTEDIT_K_SHIFT:
+#endif
case STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT: {
StbFindState find;
stb_textedit_clamp(str, state);
stb_textedit_prep_selection_at_cursor(state);
stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
- state->cursor = state->select_end = find.first_char + find.length;
state->has_preferred_x = 0;
+ state->cursor = find.first_char + find.length;
+ if (find.length > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) == STB_TEXTEDIT_NEWLINE)
+ --state->cursor;
+ state->select_end = state->cursor;
break;
}
@@ -1008,13 +1058,13 @@ static void stb_textedit_discard_undo(StbUndoState *state)
int n = state->undo_rec[0].insert_length, i;
// delete n characters from all other records
state->undo_char_point = state->undo_char_point - (short) n; // vsnet05
- memmove(state->undo_char, state->undo_char + n, (size_t) ((size_t)state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
+ STB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
for (i=0; i < state->undo_point; ++i)
if (state->undo_rec[i].char_storage >= 0)
state->undo_rec[i].char_storage = state->undo_rec[i].char_storage - (short) n; // vsnet05 // @OPTIMIZE: get rid of char_storage and infer it
}
--state->undo_point;
- memmove(state->undo_rec, state->undo_rec+1, (size_t) ((size_t)state->undo_point*sizeof(state->undo_rec[0])));
+ STB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
}
}
@@ -1032,13 +1082,13 @@ static void stb_textedit_discard_redo(StbUndoState *state)
int n = state->undo_rec[k].insert_length, i;
// delete n characters from all other records
state->redo_char_point = state->redo_char_point + (short) n; // vsnet05
- memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE)));
+ STB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE)));
for (i=state->redo_point; i < k; ++i)
if (state->undo_rec[i].char_storage >= 0)
state->undo_rec[i].char_storage = state->undo_rec[i].char_storage + (short) n; // vsnet05
}
++state->redo_point;
- memmove(state->undo_rec + state->redo_point-1, state->undo_rec + state->redo_point, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0])));
+ STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point-1, state->undo_rec + state->redo_point, (size_t) ((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0])));
}
}
diff --git a/3rdparty/bgfx/3rdparty/stb/stb_truetype.h b/3rdparty/bgfx/3rdparty/stb/stb_truetype.h
index 98f1319e844..c99f5d63e01 100644
--- a/3rdparty/bgfx/3rdparty/stb/stb_truetype.h
+++ b/3rdparty/bgfx/3rdparty/stb/stb_truetype.h
@@ -27,6 +27,10 @@
// Mikko Mononen: compound shape support, more cmap formats
// Tor Andersson: kerning, subpixel rendering
//
+// Misc other:
+// Ryan Gordon
+// Simon Glass
+//
// Bug/warning reports/fixes:
// "Zer" on mollyrocket (with fix)
// Cass Everitt
@@ -45,13 +49,18 @@
// Omar Cornut
// github:aloucks
// Peter LaValle
+// Sergey Popov
// Giumo X. Clanjor
-//
-// Misc other:
-// Ryan Gordon
+// Higor Euripedes
+// Thomas Fields
+// Derek Vinyard
//
// VERSION HISTORY
//
+// 1.11 (2016-04-02) fix unused-variable warning
+// 1.10 (2016-04-02) user-defined fabs(); rare memory leak; remove duplicate typedef
+// 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use allocation userdata properly
+// 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges
// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints;
// variant PackFontRanges to pack and render in separate phases;
// fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?);
@@ -68,9 +77,9 @@
//
// LICENSE
//
-// This software is in the public domain. Where that dedication is not
-// recognized, you are granted a perpetual, irrevocable license to copy,
-// distribute, and modify this file as you see fit.
+// This software is dual-licensed to the public domain and under the following
+// license: you are granted a perpetual, irrevocable license to copy, modify,
+// publish, and distribute this file as you see fit.
//
// USAGE
//
@@ -406,6 +415,11 @@ int main(int arg, char **argv)
#define STBTT_sqrt(x) sqrt(x)
#endif
+ #ifndef STBTT_fabs
+ #include <math.h>
+ #define STBTT_fabs(x) fabs(x)
+ #endif
+
// #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h
#ifndef STBTT_malloc
#include <stdlib.h>
@@ -629,7 +643,7 @@ STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index);
// The following structure is defined publically so you can declare one on
// the stack or as a global or etc, but you should treat it as opaque.
-typedef struct stbtt_fontinfo
+struct stbtt_fontinfo
{
void * userdata;
unsigned char * data; // pointer to .ttf file
@@ -640,7 +654,7 @@ typedef struct stbtt_fontinfo
int loca,head,glyf,hhea,hmtx,kern; // table locations as offset from start of .ttf
int index_map; // a cmap mapping for our chosen character encoding
int indexToLocFormat; // format needed to map from glyph index to glyph
-} stbtt_fontinfo;
+};
STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset);
// Given an offset into the file that defines a font, this function builds
@@ -808,7 +822,16 @@ typedef struct
unsigned char *pixels;
} stbtt__bitmap;
-STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata);
+// rasterize a shape with quadratic beziers into a bitmap
+STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, // 1-channel bitmap to draw into
+ float flatness_in_pixels, // allowable error of curve in pixels
+ stbtt_vertex *vertices, // array of vertices defining shape
+ int num_verts, // number of vertices in above array
+ float scale_x, float scale_y, // scale applied to input vertices
+ float shift_x, float shift_y, // translation applied to input vertices
+ int x_off, int y_off, // another translation applied to input
+ int invert, // if non-zero, vertically flip shape
+ void *userdata); // context for to STBTT_MALLOC
//////////////////////////////////////////////////////////////////////////////
//
@@ -933,6 +956,12 @@ typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERS
#define STBTT_RASTERIZER_VERSION 2
#endif
+#ifdef _MSC_VER
+#define STBTT__NOTUSED(v) (void)(v)
+#else
+#define STBTT__NOTUSED(v) (void)sizeof(v)
+#endif
+
//////////////////////////////////////////////////////////////////////////
//
// accessors to parse data from file
@@ -1550,7 +1579,7 @@ STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v)
STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1)
{
- int x0,y0,x1,y1;
+ int x0=0,y0=0,x1,y1; // =0 suppresses compiler warning
if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) {
// e.g. space character
if (ix0) *ix0 = 0;
@@ -1666,6 +1695,7 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i
{
stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata);
float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
+ STBTT_assert(z != NULL);
if (!z) return z;
// round dx down to avoid overshooting
@@ -1687,10 +1717,11 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i
{
stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata);
float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
+ STBTT_assert(z != NULL);
//STBTT_assert(e->y0 <= start_point);
if (!z) return z;
z->fdx = dxdy;
- z->fdy = (1/dxdy);
+ z->fdy = dxdy != 0.0f ? (1.0f/dxdy) : 0.0f;
z->fx = e->x0 + dxdy * (start_point - e->y0);
z->fx -= off_x;
z->direction = e->invert ? 1.0f : -1.0f;
@@ -1751,7 +1782,7 @@ static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__ac
static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)
{
- stbtt__hheap hh = { 0 };
+ stbtt__hheap hh = { 0, 0, 0 };
stbtt__active_edge *active = NULL;
int y,j=0;
int max_weight = (255 / vsubsample); // weight per vertical scanline
@@ -1811,21 +1842,23 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
while (e->y0 <= scan_y) {
if (e->y1 > scan_y) {
stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata);
- // find insertion point
- if (active == NULL)
- active = z;
- else if (z->x < active->x) {
- // insert at front
- z->next = active;
- active = z;
- } else {
- // find thing to insert AFTER
- stbtt__active_edge *p = active;
- while (p->next && p->next->x < z->x)
- p = p->next;
- // at this point, p->next->x is NOT < z->x
- z->next = p->next;
- p->next = z;
+ if (z != NULL) {
+ // find insertion point
+ if (active == NULL)
+ active = z;
+ else if (z->x < active->x) {
+ // insert at front
+ z->next = active;
+ active = z;
+ } else {
+ // find thing to insert AFTER
+ stbtt__active_edge *p = active;
+ while (p->next && p->next->x < z->x)
+ p = p->next;
+ // at this point, p->next->x is NOT < z->x
+ z->next = p->next;
+ p->next = z;
+ }
}
}
++e;
@@ -1913,7 +1946,7 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
float dx = e->fdx;
float xb = x0 + dx;
float x_top, x_bottom;
- float y0,y1;
+ float sy0,sy1;
float dy = e->fdy;
STBTT_assert(e->sy <= y_bottom && e->ey >= y_top);
@@ -1922,17 +1955,17 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
// line with y_top, but that may be off the line segment.
if (e->sy > y_top) {
x_top = x0 + dx * (e->sy - y_top);
- y0 = e->sy;
+ sy0 = e->sy;
} else {
x_top = x0;
- y0 = y_top;
+ sy0 = y_top;
}
if (e->ey < y_bottom) {
x_bottom = x0 + dx * (e->ey - y_top);
- y1 = e->ey;
+ sy1 = e->ey;
} else {
x_bottom = xb;
- y1 = y_bottom;
+ sy1 = y_bottom;
}
if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) {
@@ -1942,7 +1975,7 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
float height;
// simple case, only spans one pixel
int x = (int) x_top;
- height = y1 - y0;
+ height = sy1 - sy0;
STBTT_assert(x >= 0 && x < len);
scanline[x] += e->direction * (1-((x_top - x) + (x_bottom-x))/2) * height;
scanline_fill[x] += e->direction * height; // everything right of this pixel is filled
@@ -1953,9 +1986,9 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
if (x_top > x_bottom) {
// flip scanline vertically; signed area is the same
float t;
- y0 = y_bottom - (y0 - y_top);
- y1 = y_bottom - (y1 - y_top);
- t = y0, y0 = y1, y1 = t;
+ sy0 = y_bottom - (sy0 - y_top);
+ sy1 = y_bottom - (sy1 - y_top);
+ t = sy0, sy0 = sy1, sy1 = t;
t = x_bottom, x_bottom = x_top, x_top = t;
dx = -dx;
dy = -dy;
@@ -1969,7 +2002,7 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
sign = e->direction;
// area of the rectangle covered from y0..y_crossing
- area = sign * (y_crossing-y0);
+ area = sign * (y_crossing-sy0);
// area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing)
scanline[x1] += area * (1-((x_top - x1)+(x1+1-x1))/2);
@@ -1980,11 +2013,11 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
}
y_crossing += dy * (x2 - (x1+1));
- STBTT_assert(fabs(area) <= 1.01f);
+ STBTT_assert(STBTT_fabs(area) <= 1.01f);
- scanline[x2] += area + sign * (1-((x2-x2)+(x_bottom-x2))/2) * (y1-y_crossing);
+ scanline[x2] += area + sign * (1-((x2-x2)+(x_bottom-x2))/2) * (sy1-y_crossing);
- scanline_fill[x2] += sign * (y1-y0);
+ scanline_fill[x2] += sign * (sy1-sy0);
}
} else {
// if edge goes outside of box we're drawing, we require
@@ -2053,13 +2086,13 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
// directly AA rasterize edges w/o supersampling
static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)
{
- (void)vsubsample;
- stbtt__hheap hh;
- memset(&hh, 0, sizeof(hh));
+ stbtt__hheap hh = { 0, 0, 0 };
stbtt__active_edge *active = NULL;
int y,j=0, i;
float scanline_data[129], *scanline, *scanline2;
+ STBTT__NOTUSED(vsubsample);
+
if (result->w > 64)
scanline = (float *) STBTT_malloc((result->w*2+1) * sizeof(float), userdata);
else
@@ -2095,11 +2128,15 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
// insert all edges that start before the bottom of this scanline
while (e->y0 <= scan_y_bottom) {
- stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata);
- STBTT_assert(z->ey >= scan_y_top);
- // insert at front
- z->next = active;
- active = z;
+ if (e->y0 != e->y1) {
+ stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata);
+ if (z != NULL) {
+ STBTT_assert(z->ey >= scan_y_top);
+ // insert at front
+ z->next = active;
+ active = z;
+ }
+ }
++e;
}
@@ -2114,7 +2151,7 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
int m;
sum += scanline2[i];
k = scanline[i] + sum;
- k = (float) fabs(k)*255 + 0.5f;
+ k = (float) STBTT_fabs(k)*255 + 0.5f;
m = (int) k;
if (m > 255) m = 255;
result->pixels[j*result->stride + i] = (unsigned char) m;
@@ -2415,7 +2452,10 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info
if (scale_x == 0) scale_x = scale_y;
if (scale_y == 0) {
- if (scale_x == 0) return NULL;
+ if (scale_x == 0) {
+ STBTT_free(vertices, info->userdata);
+ return NULL;
+ }
scale_y = scale_x;
}
@@ -2507,6 +2547,7 @@ STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // fo
float scale;
int x,y,bottom_y, i;
stbtt_fontinfo f;
+ f.userdata = NULL;
if (!stbtt_InitFont(&f, data, offset))
return -1;
STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
@@ -2570,11 +2611,6 @@ STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int
//
#ifndef STB_RECT_PACK_VERSION
-#ifdef _MSC_VER
-#define STBTT__NOTUSED(v) (void)(v)
-#else
-#define STBTT__NOTUSED(v) (void)sizeof(v)
-#endif
typedef int stbrp_coord;
@@ -2700,6 +2736,7 @@ static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_i
unsigned char buffer[STBTT_MAX_OVERSAMPLE];
int safe_w = w - kernel_width;
int j;
+ STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze
for (j=0; j < h; ++j) {
int i;
unsigned int total;
@@ -2761,6 +2798,7 @@ static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_i
unsigned char buffer[STBTT_MAX_OVERSAMPLE];
int safe_h = h - kernel_width;
int j;
+ STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze
for (j=0; j < w; ++j) {
int i;
unsigned int total;
@@ -2842,7 +2880,7 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fon
ranges[i].v_oversample = (unsigned char) spc->v_oversample;
for (j=0; j < ranges[i].num_chars; ++j) {
int x0,y0,x1,y1;
- int codepoint = ranges[i].first_unicode_codepoint_in_range ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
+ int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
int glyph = stbtt_FindGlyphIndex(info, codepoint);
stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
scale * spc->h_oversample,
@@ -2883,7 +2921,7 @@ STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt
if (r->was_packed) {
stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
int advance, lsb, x0,y0,x1,y1;
- int codepoint = ranges[i].first_unicode_codepoint_in_range ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
+ int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
int glyph = stbtt_FindGlyphIndex(info, codepoint);
stbrp_coord pad = (stbrp_coord) spc->padding;
@@ -2969,6 +3007,7 @@ STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontd
if (rects == NULL)
return 0;
+ info.userdata = spc->user_allocator_context;
stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index));
n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects);
@@ -3186,6 +3225,12 @@ STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection, const
// FULL VERSION HISTORY
//
+// 1.11 (2016-04-02) fix unused-variable warning
+// 1.10 (2016-04-02) allow user-defined fabs() replacement
+// fix memory leak if fontsize=0.0
+// fix warning from duplicate typedef
+// 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use alloc userdata for PackFontRanges
+// 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges
// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints;
// allow PackFontRanges to pack and render in separate phases;
// fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?);
diff --git a/3rdparty/bgfx/CONTRUBUTING.md b/3rdparty/bgfx/CONTRIBUTING.md
index e65eb715934..e6931eafcfb 100644
--- a/3rdparty/bgfx/CONTRUBUTING.md
+++ b/3rdparty/bgfx/CONTRIBUTING.md
@@ -4,6 +4,9 @@ Everyone is welcome to contribute to bgfx by submitting bug reports, testing on
different platforms, writing examples, improving documentation, profiling and
optimizing, helping newcomers, telling others about bgfx, etc.
+If you have just quick oneliner question it's prefereable to ask it at chat
+https://gitter.im/bkaradzic/bgfx instead opening new issue.
+
## Submitting bugs
Unless bug is trivial, and easy to explain and understand, the fastest way to
diff --git a/3rdparty/bgfx/README.md b/3rdparty/bgfx/README.md
index ca00102568c..9c163f9c644 100644
--- a/3rdparty/bgfx/README.md
+++ b/3rdparty/bgfx/README.md
@@ -1,6 +1,8 @@
[bgfx](https://github.com/bkaradzic/bgfx) - Cross-platform rendering library
============================================================================
+[![Join the chat at https://gitter.im/bkaradzic/bgfx](https://badges.gitter.im/bkaradzic/bgfx.svg)](https://gitter.im/bkaradzic/bgfx)
+
[![Build Status](https://travis-ci.org/bkaradzic/bgfx.svg?branch=master)](https://travis-ci.org/bkaradzic/bgfx)
[![Build status](https://ci.appveyor.com/api/projects/status/ipa3ojgeaet1oko5?svg=true)](https://ci.appveyor.com/project/bkaradzic/bgfx)
@@ -25,7 +27,7 @@ Supported rendering backends:
Supported HMD:
- * OculusVR (0.4.2+)
+ * OculusVR (1.3.0)
Supported platforms:
diff --git a/3rdparty/bgfx/examples/00-helloworld/helloworld.cpp b/3rdparty/bgfx/examples/00-helloworld/helloworld.cpp
index e2e8a599a15..92996ae0314 100644
--- a/3rdparty/bgfx/examples/00-helloworld/helloworld.cpp
+++ b/3rdparty/bgfx/examples/00-helloworld/helloworld.cpp
@@ -7,7 +7,6 @@
#include "common.h"
#include "bgfx_utils.h"
#include "logo.h"
-#include "imgui/imgui.h"
class ExampleHelloWorld : public entry::AppI
{
@@ -29,111 +28,23 @@ class ExampleHelloWorld : public entry::AppI
// Set view 0 clear state.
bgfx::setViewClear(0
, BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
- , 0x000000ff
+ , 0x303030ff
, 1.0f
, 0
);
- imguiCreate();
- ImGui::GetIO().FontGlobalScale = 1.5;
}
virtual int shutdown() BX_OVERRIDE
{
- // Cleanup.
- imguiDestroy();
-
// Shutdown bgfx.
bgfx::shutdown();
return 0;
}
- void displayMainMenu()
- {
- if (ImGui::BeginMainMenuBar())
- {
- if (ImGui::BeginMenu("Left"))
- {
- if (ImGui::MenuItem("Brief", "CTRL+1")) {}
- if (ImGui::MenuItem("Medium", "CTRL+2")) {}
- if (ImGui::MenuItem("Two columns", "CTRL+3")) {}
- if (ImGui::MenuItem("Full (name)", "CTRL+4")) {}
- if (ImGui::MenuItem("Full (size, time)", "CTRL+5")) {}
- if (ImGui::MenuItem("Full (access)", "CTRL+6")) {}
- ImGui::Separator();
- if (ImGui::BeginMenu("Sort mode"))
- {
- ImGui::MenuItem("Name");
- ImGui::MenuItem("Extension");
- ImGui::MenuItem("Modif. Time");
- ImGui::MenuItem("Size");
- ImGui::MenuItem("Unsorted");
- ImGui::EndMenu();
- }
- if (ImGui::MenuItem("Change source")) {}
- ImGui::EndMenu();
- }
- if (ImGui::BeginMenu("Files"))
- {
- if (ImGui::MenuItem("User menu", "F2")) {}
- if (ImGui::MenuItem("View", "F3")) {}
- if (ImGui::MenuItem("Edit", "F4")) {}
- if (ImGui::MenuItem("Copy", "F5")) {}
- if (ImGui::MenuItem("Rename or move", "F6")) {}
- if (ImGui::MenuItem("Make directory", "F7")) {}
- if (ImGui::MenuItem("Delete", "F8")) {}
- ImGui::Separator();
- if (ImGui::MenuItem("File attributes", "CTRL+A")) {}
- if (ImGui::MenuItem("Apply command", "CTRL+G")) {}
- ImGui::Separator();
- if (ImGui::MenuItem("Select group")) {}
- if (ImGui::MenuItem("Unselect group")) {}
- if (ImGui::MenuItem("Invert selection")) {}
- ImGui::EndMenu();
- }
- if (ImGui::BeginMenu("Commands"))
- {
- if (ImGui::MenuItem("Find file", "ALT+F7")) {}
- if (ImGui::MenuItem("History", "ALT+F8")) {}
- if (ImGui::MenuItem("Maximize window", "ALT+F9")) {}
- ImGui::Separator();
- if (ImGui::MenuItem("Panel on/off", "CTRL+O")) {}
- if (ImGui::MenuItem("Equal panels", "CTRL+=")) {}
- ImGui::EndMenu();
- }
- if (ImGui::BeginMenu("Options"))
- {
- if (ImGui::MenuItem("Settings")) {}
- ImGui::EndMenu();
- }
- if (ImGui::BeginMenu("Right"))
- {
- if (ImGui::MenuItem("Brief", "CTRL+1")) {}
- if (ImGui::MenuItem("Medium", "CTRL+2")) {}
- if (ImGui::MenuItem("Two columns", "CTRL+3")) {}
- if (ImGui::MenuItem("Full (name)", "CTRL+4")) {}
- if (ImGui::MenuItem("Full (size, time)", "CTRL+5")) {}
- if (ImGui::MenuItem("Full (access)", "CTRL+6")) {}
- ImGui::Separator();
- if (ImGui::BeginMenu("Sort mode"))
- {
- ImGui::MenuItem("Name");
- ImGui::MenuItem("Extension");
- ImGui::MenuItem("Modif. Time");
- ImGui::MenuItem("Size");
- ImGui::MenuItem("Unsorted");
- ImGui::EndMenu();
- }
- if (ImGui::MenuItem("Change source")) {}
- ImGui::EndMenu();
- }
- ImGui::EndMainMenuBar();
- }
- }
-
bool update() BX_OVERRIDE
{
- if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
+ if (!entry::processEvents(m_width, m_height, m_debug, m_reset) )
{
// Set view 0 default viewport.
bgfx::setViewRect(0, 0, 0, m_width, m_height);
@@ -142,91 +53,18 @@ class ExampleHelloWorld : public entry::AppI
// if no other draw calls are submitted to view 0.
bgfx::touch(0);
- imguiBeginFrame(m_mouseState.m_mx
- , m_mouseState.m_my
- , (m_mouseState.m_buttons[entry::MouseButton::Left] ? IMGUI_MBUT_LEFT : 0)
- | (m_mouseState.m_buttons[entry::MouseButton::Right] ? IMGUI_MBUT_RIGHT : 0)
- , m_mouseState.m_mz
- , m_width
- , m_height
- );
- displayMainMenu();
- ImGui::SetNextWindowPos(ImVec2(0, 32));
- ImGui::SetNextWindowSize(ImVec2(m_width/2, m_height - 32));
- if (ImGui::Begin("Window1", nullptr, ImVec2(m_width/2, m_height-32), 1.0f, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar))
- {
- ImGui::PushStyleVar(ImGuiStyleVar_ChildWindowRounding, 5.0f);
- ImGui::BeginChild("Sub1", ImVec2(0, m_height - 48), true);
-
-
- ImGui::Columns(4, "mycolumns");
- ImGui::Separator();
- ImGui::Text("ID"); ImGui::NextColumn();
- ImGui::Text("Name"); ImGui::NextColumn();
- ImGui::Text("Path"); ImGui::NextColumn();
- ImGui::Text("Flags"); ImGui::NextColumn();
- ImGui::Separator();
- const char* names[3] = { "One", "Two", "Three" };
- const char* paths[3] = { "/path/one", "/path/two", "/path/three" };
- static int selected = -1;
- for (int i = 0; i < 50; i++)
- {
- char label[32];
- sprintf(label, "%04d", i);
- if (ImGui::Selectable(label, selected == i, ImGuiSelectableFlags_SpanAllColumns))
- selected = i;
- ImGui::NextColumn();
- ImGui::Text(names[i%3]); ImGui::NextColumn();
- ImGui::Text(paths[i % 3]); ImGui::NextColumn();
- ImGui::Text("...."); ImGui::NextColumn();
- }
- ImGui::Columns(1);
- ImGui::Separator();
-
-
-
- ImGui::EndChild();
- ImGui::PopStyleVar();
- }
- ImGui::End();
- ImGui::SameLine();
- ImGui::SetNextWindowPos(ImVec2(m_width / 2, 32));
- ImGui::SetNextWindowSize(ImVec2(m_width / 2, m_height - 32));
- if (ImGui::Begin("Window2", nullptr, ImVec2(m_width/2, m_height - 32), 1.0f, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar))
- {
- ImGui::PushStyleVar(ImGuiStyleVar_ChildWindowRounding, 5.0f);
- ImGui::BeginChild("Sub2", ImVec2(0, m_height - 48), true);
-
- ImGui::Columns(4, "mycolumns");
- ImGui::Separator();
- ImGui::Text("ID"); ImGui::NextColumn();
- ImGui::Text("Name"); ImGui::NextColumn();
- ImGui::Text("Path"); ImGui::NextColumn();
- ImGui::Text("Flags"); ImGui::NextColumn();
- ImGui::Separator();
- const char* names[3] = { "One", "Two", "Three" };
- const char* paths[3] = { "/path/one", "/path/two", "/path/three" };
- static int selected = -1;
- for (int i = 0; i < 3; i++)
- {
- char label[32];
- sprintf(label, "%04d", i);
- if (ImGui::Selectable(label, selected == i, ImGuiSelectableFlags_SpanAllColumns))
- selected = i;
- ImGui::NextColumn();
- ImGui::Text(names[i]); ImGui::NextColumn();
- ImGui::Text(paths[i]); ImGui::NextColumn();
- ImGui::Text("...."); ImGui::NextColumn();
- }
- ImGui::Columns(1);
- ImGui::Separator();
-
-
- ImGui::EndChild();
- ImGui::PopStyleVar();
- }
- ImGui::End();
- imguiEndFrame();
+ // Use debug font to print information about this example.
+ bgfx::dbgTextClear();
+ bgfx::dbgTextImage(bx::uint16_max(m_width /2/8, 20)-20
+ , bx::uint16_max(m_height/2/16, 6)-6
+ , 40
+ , 12
+ , s_logo
+ , 160
+ );
+ bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/00-helloworld");
+ bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Initialization and debug text.");
+
// Advance to next frame. Rendering thread will be kicked to
// process submitted rendering primitives.
bgfx::frame();
@@ -241,7 +79,6 @@ class ExampleHelloWorld : public entry::AppI
uint32_t m_height;
uint32_t m_debug;
uint32_t m_reset;
- entry::MouseState m_mouseState;
};
ENTRY_IMPLEMENT_MAIN(ExampleHelloWorld);
diff --git a/3rdparty/bgfx/examples/01-cubes/cubes.cpp b/3rdparty/bgfx/examples/01-cubes/cubes.cpp
index bf88eb3f7f0..97cf605294c 100644
--- a/3rdparty/bgfx/examples/01-cubes/cubes.cpp
+++ b/3rdparty/bgfx/examples/01-cubes/cubes.cpp
@@ -143,11 +143,7 @@ class ExampleCubes : public entry::AppI
{
float view[16];
bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye);
-
- float proj[16];
- bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 100.0f);
-
- bgfx::setViewTransform(0, view, proj);
+ bgfx::setViewTransform(0, view, hmd->eye[0].projection);
// Set view 0 default viewport.
//
diff --git a/3rdparty/bgfx/examples/02-metaballs/metaballs.cpp b/3rdparty/bgfx/examples/02-metaballs/metaballs.cpp
index bedf55497eb..f0f20e39cc9 100644
--- a/3rdparty/bgfx/examples/02-metaballs/metaballs.cpp
+++ b/3rdparty/bgfx/examples/02-metaballs/metaballs.cpp
@@ -577,11 +577,7 @@ class ExampleMetaballs : public entry::AppI
{
float view[16];
bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye);
-
- float proj[16];
- bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 100.0f);
-
- bgfx::setViewTransform(0, view, proj);
+ bgfx::setViewTransform(0, view, hmd->eye[0].projection);
// Set view 0 default viewport.
//
diff --git a/3rdparty/bgfx/examples/03-raymarch/raymarch.cpp b/3rdparty/bgfx/examples/03-raymarch/raymarch.cpp
index 60a4664546e..0e4a84c3dc9 100644
--- a/3rdparty/bgfx/examples/03-raymarch/raymarch.cpp
+++ b/3rdparty/bgfx/examples/03-raymarch/raymarch.cpp
@@ -107,7 +107,7 @@ class ExampleRaymarch : public entry::AppI
void init(int _argc, char** _argv) BX_OVERRIDE
{
Args args(_argc, _argv);
-
+
m_width = 1280;
m_height = 720;
m_debug = BGFX_DEBUG_TEXT;
@@ -127,18 +127,8 @@ class ExampleRaymarch : public entry::AppI
, 0
);
- // Setup root path for binary shaders. Shader binaries are different
- // for each renderer.
- switch (bgfx::getRendererType() )
- {
- default:
- break;
-
- case bgfx::RendererType::OpenGL:
- case bgfx::RendererType::OpenGLES:
- s_oglNdc = true;
- break;
- }
+ const bgfx::Caps* caps = bgfx::getCaps();
+ s_oglNdc = caps->homogeneousDepth;
// Create vertex stream declaration.
PosColorTexCoord0Vertex::init();
diff --git a/3rdparty/bgfx/examples/04-mesh/mesh.cpp b/3rdparty/bgfx/examples/04-mesh/mesh.cpp
index bfe61df6a3f..f7f8b7e96ce 100644
--- a/3rdparty/bgfx/examples/04-mesh/mesh.cpp
+++ b/3rdparty/bgfx/examples/04-mesh/mesh.cpp
@@ -91,11 +91,7 @@ class ExampleMesh : public entry::AppI
{
float view[16];
bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye);
-
- float proj[16];
- bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 100.0f);
-
- bgfx::setViewTransform(0, view, proj);
+ bgfx::setViewTransform(0, view, hmd->eye[0].projection);
// Set view 0 default viewport.
//
diff --git a/3rdparty/bgfx/examples/05-instancing/instancing.cpp b/3rdparty/bgfx/examples/05-instancing/instancing.cpp
index 6e854b20785..1a0f0b69cd8 100644
--- a/3rdparty/bgfx/examples/05-instancing/instancing.cpp
+++ b/3rdparty/bgfx/examples/05-instancing/instancing.cpp
@@ -160,11 +160,7 @@ class ExampleInstancing : public entry::AppI
{
float view[16];
bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye);
-
- float proj[16];
- bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 100.0f);
-
- bgfx::setViewTransform(0, view, proj);
+ bgfx::setViewTransform(0, view, hmd->eye[0].projection);
// Set view 0 default viewport.
//
diff --git a/3rdparty/bgfx/examples/06-bump/bump.cpp b/3rdparty/bgfx/examples/06-bump/bump.cpp
index bc5f9e74b7e..da6cff3d78e 100644
--- a/3rdparty/bgfx/examples/06-bump/bump.cpp
+++ b/3rdparty/bgfx/examples/06-bump/bump.cpp
@@ -225,11 +225,7 @@ class ExampleBump : public entry::AppI
{
float view[16];
bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye);
-
- float proj[16];
- bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 100.0f);
-
- bgfx::setViewTransform(0, view, proj);
+ bgfx::setViewTransform(0, view, hmd->eye[0].projection);
// Set view 0 default viewport.
//
diff --git a/3rdparty/bgfx/examples/09-hdr/hdr.cpp b/3rdparty/bgfx/examples/09-hdr/hdr.cpp
index bee42aed2bf..dfe6f7dd390 100644
--- a/3rdparty/bgfx/examples/09-hdr/hdr.cpp
+++ b/3rdparty/bgfx/examples/09-hdr/hdr.cpp
@@ -8,7 +8,6 @@
#include "imgui/imgui.h"
static float s_texelHalf = 0.0f;
-static bool s_originBottomLeft = false;
struct PosColorTexCoord0Vertex
{
@@ -230,9 +229,8 @@ class ExampleHDR : public entry::AppI
// Imgui.
imguiCreate();
- const bgfx::RendererType::Enum renderer = bgfx::getRendererType();
- s_texelHalf = bgfx::RendererType::Direct3D9 == renderer ? 0.5f : 0.0f;
- s_originBottomLeft = bgfx::RendererType::OpenGL == renderer || bgfx::RendererType::OpenGLES == renderer;
+ m_caps = bgfx::getCaps();
+ s_texelHalf = bgfx::RendererType::Direct3D9 == m_caps->rendererType ? 0.5f : 0.0f;
m_oldWidth = 0;
m_oldHeight = 0;
@@ -441,35 +439,35 @@ class ExampleHDR : public entry::AppI
setOffsets2x2Lum(u_offset, 128, 128);
bgfx::setTexture(0, s_texColor, m_fbtextures[0]);
bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
- screenSpaceQuad(128.0f, 128.0f, s_originBottomLeft);
+ screenSpaceQuad(128.0f, 128.0f, m_caps->originBottomLeft);
bgfx::submit(2, m_lumProgram);
// Downscale luminance 0.
setOffsets4x4Lum(u_offset, 128, 128);
bgfx::setTexture(0, s_texColor, m_lum[0]);
bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
- screenSpaceQuad(64.0f, 64.0f, s_originBottomLeft);
+ screenSpaceQuad(64.0f, 64.0f, m_caps->originBottomLeft);
bgfx::submit(3, m_lumAvgProgram);
// Downscale luminance 1.
setOffsets4x4Lum(u_offset, 64, 64);
bgfx::setTexture(0, s_texColor, m_lum[1]);
bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
- screenSpaceQuad(16.0f, 16.0f, s_originBottomLeft);
+ screenSpaceQuad(16.0f, 16.0f, m_caps->originBottomLeft);
bgfx::submit(4, m_lumAvgProgram);
// Downscale luminance 2.
setOffsets4x4Lum(u_offset, 16, 16);
bgfx::setTexture(0, s_texColor, m_lum[2]);
bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
- screenSpaceQuad(4.0f, 4.0f, s_originBottomLeft);
+ screenSpaceQuad(4.0f, 4.0f, m_caps->originBottomLeft);
bgfx::submit(5, m_lumAvgProgram);
// Downscale luminance 3.
setOffsets4x4Lum(u_offset, 4, 4);
bgfx::setTexture(0, s_texColor, m_lum[3]);
bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
- screenSpaceQuad(1.0f, 1.0f, s_originBottomLeft);
+ screenSpaceQuad(1.0f, 1.0f, m_caps->originBottomLeft);
bgfx::submit(6, m_lumAvgProgram);
float tonemap[4] = { m_middleGray, square(m_white), m_threshold, m_time };
@@ -480,13 +478,13 @@ class ExampleHDR : public entry::AppI
bgfx::setTexture(0, s_texColor, m_fbtextures[0]);
bgfx::setTexture(1, s_texLum, m_lum[4]);
bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
- screenSpaceQuad( (float)m_width/2.0f, (float)m_height/2.0f, s_originBottomLeft);
+ screenSpaceQuad( (float)m_width/2.0f, (float)m_height/2.0f, m_caps->originBottomLeft);
bgfx::submit(7, m_brightProgram);
// m_blur m_bright pass vertically.
bgfx::setTexture(0, s_texColor, m_bright);
bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
- screenSpaceQuad( (float)m_width/8.0f, (float)m_height/8.0f, s_originBottomLeft);
+ screenSpaceQuad( (float)m_width/8.0f, (float)m_height/8.0f, m_caps->originBottomLeft);
bgfx::submit(8, m_blurProgram);
// m_blur m_bright pass horizontally, do tonemaping and combine.
@@ -494,7 +492,7 @@ class ExampleHDR : public entry::AppI
bgfx::setTexture(1, s_texLum, m_lum[4]);
bgfx::setTexture(2, s_texBlur, m_blur);
bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
- screenSpaceQuad( (float)m_width, (float)m_height, s_originBottomLeft);
+ screenSpaceQuad( (float)m_width, (float)m_height, m_caps->originBottomLeft);
bgfx::submit(9, m_tonemapProgram);
if (bgfx::isValid(m_rb) )
@@ -558,6 +556,7 @@ class ExampleHDR : public entry::AppI
int32_t m_scrollArea;
+ const bgfx::Caps* m_caps;
float m_time;
};
diff --git a/3rdparty/bgfx/examples/12-lod/lod.cpp b/3rdparty/bgfx/examples/12-lod/lod.cpp
index ef37d254c11..c66db5a24dc 100644
--- a/3rdparty/bgfx/examples/12-lod/lod.cpp
+++ b/3rdparty/bgfx/examples/12-lod/lod.cpp
@@ -174,11 +174,7 @@ class ExampleLod : public entry::AppI
{
float view[16];
bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye);
-
- float proj[16];
- bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 100.0f);
-
- bgfx::setViewTransform(0, view, proj);
+ bgfx::setViewTransform(0, view, hmd->eye[0].projection);
// Set view 0 default viewport.
//
diff --git a/3rdparty/bgfx/examples/14-shadowvolumes/shadowvolumes.cpp b/3rdparty/bgfx/examples/14-shadowvolumes/shadowvolumes.cpp
index fbdc8804b02..093b168d42f 100644
--- a/3rdparty/bgfx/examples/14-shadowvolumes/shadowvolumes.cpp
+++ b/3rdparty/bgfx/examples/14-shadowvolumes/shadowvolumes.cpp
@@ -1866,22 +1866,9 @@ int _main_(int _argc, char** _argv)
// Enable debug text.
bgfx::setDebug(debug);
- // Setup root path for binary shaders. Shader binaries are different
- // for each renderer.
- switch (bgfx::getRendererType() )
- {
- case bgfx::RendererType::Direct3D9:
- s_texelHalf = 0.5f;
- break;
-
- case bgfx::RendererType::OpenGL:
- case bgfx::RendererType::OpenGLES:
- s_oglNdc = true;
- break;
-
- default:
- break;
- }
+ const bgfx::Caps* caps = bgfx::getCaps();
+ s_oglNdc = caps->homogeneousDepth;
+ s_texelHalf = bgfx::RendererType::Direct3D9 == caps->rendererType ? 0.5f : 0.0f;
// Imgui
imguiCreate();
diff --git a/3rdparty/bgfx/examples/21-deferred/deferred.cpp b/3rdparty/bgfx/examples/21-deferred/deferred.cpp
index 2f8fb5d3816..fbf5c546022 100644
--- a/3rdparty/bgfx/examples/21-deferred/deferred.cpp
+++ b/3rdparty/bgfx/examples/21-deferred/deferred.cpp
@@ -16,7 +16,6 @@
#define RENDER_PASS_DEBUG_GBUFFER_ID 4
static float s_texelHalf = 0.0f;
-static bool s_originBottomLeft = false;
struct PosNormalTangentTexcoordVertex
{
@@ -218,7 +217,7 @@ class ExampleDeferred : public entry::AppI
void init(int _argc, char** _argv) BX_OVERRIDE
{
Args args(_argc, _argv);
-
+
m_width = 1280;
m_height = 720;
m_debug = BGFX_DEBUG_TEXT;
@@ -311,7 +310,6 @@ class ExampleDeferred : public entry::AppI
m_timeOffset = bx::getHPCounter();
const bgfx::RendererType::Enum renderer = bgfx::getRendererType();
s_texelHalf = bgfx::RendererType::Direct3D9 == renderer ? 0.5f : 0.0f;
- s_originBottomLeft = bgfx::RendererType::OpenGL == renderer || bgfx::RendererType::OpenGLES == renderer;
// Get renderer capabilities info.
m_caps = bgfx::getCaps();
@@ -501,7 +499,7 @@ class ExampleDeferred : public entry::AppI
bgfx::setViewFrameBuffer(RENDER_PASS_LIGHT_ID, m_lightBuffer);
float proj[16];
- bx::mtxProj(proj, 60.0f, float(m_width)/float(m_height), 0.1f, 100.0f, s_originBottomLeft);
+ bx::mtxProj(proj, 60.0f, float(m_width)/float(m_height), 0.1f, 100.0f, m_caps->homogeneousDepth);
bgfx::setViewFrameBuffer(RENDER_PASS_GEOMETRY_ID, m_gbuffer);
bgfx::setViewTransform(RENDER_PASS_GEOMETRY_ID, view, proj);
@@ -695,7 +693,7 @@ class ExampleDeferred : public entry::AppI
| BGFX_STATE_ALPHA_WRITE
| BGFX_STATE_BLEND_ADD
);
- screenSpaceQuad( (float)m_width, (float)m_height, s_texelHalf, s_originBottomLeft);
+ screenSpaceQuad( (float)m_width, (float)m_height, s_texelHalf, m_caps->originBottomLeft);
bgfx::submit(RENDER_PASS_LIGHT_ID, m_lightProgram);
}
}
@@ -707,7 +705,7 @@ class ExampleDeferred : public entry::AppI
| BGFX_STATE_RGB_WRITE
| BGFX_STATE_ALPHA_WRITE
);
- screenSpaceQuad( (float)m_width, (float)m_height, s_texelHalf, s_originBottomLeft);
+ screenSpaceQuad( (float)m_width, (float)m_height, s_texelHalf, m_caps->originBottomLeft);
bgfx::submit(RENDER_PASS_COMBINE_ID, m_combineProgram);
if (m_showGBuffer)
diff --git a/3rdparty/bgfx/examples/21-deferred/fs_deferred_light.sc b/3rdparty/bgfx/examples/21-deferred/fs_deferred_light.sc
index 378f1eded71..81f9ad25984 100644
--- a/3rdparty/bgfx/examples/21-deferred/fs_deferred_light.sc
+++ b/3rdparty/bgfx/examples/21-deferred/fs_deferred_light.sc
@@ -72,7 +72,7 @@ vec3 clipToWorld(mat4 _invViewProj, vec3 _clipPos)
void main()
{
vec3 normal = decodeNormalUint(texture2D(s_normal, v_texcoord0).xyz);
- float deviceDepth = texture2D(s_depth, v_texcoord0).x;
+ float deviceDepth = texture2D(s_depth, v_texcoord0).x;
float depth = toClipSpaceDepth(deviceDepth);
vec3 clip = vec3(v_texcoord0 * 2.0 - 1.0, depth);
diff --git a/3rdparty/bgfx/examples/24-nbody/nbody.cpp b/3rdparty/bgfx/examples/24-nbody/nbody.cpp
index 79f722f962e..f04766a5823 100644
--- a/3rdparty/bgfx/examples/24-nbody/nbody.cpp
+++ b/3rdparty/bgfx/examples/24-nbody/nbody.cpp
@@ -305,11 +305,7 @@ int _main_(int _argc, char** _argv)
float tmp[16];
bx::mtxMul(tmp, view, viewHead);
-
- float proj[16];
- bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 10000.0f);
-
- bgfx::setViewTransform(0, tmp, proj);
+ bgfx::setViewTransform(0, tmp, hmd->eye[0].projection);
// Set view 0 default viewport.
//
diff --git a/3rdparty/bgfx/examples/26-occlusion/occlusion.cpp b/3rdparty/bgfx/examples/26-occlusion/occlusion.cpp
index 81e00f0c5fe..8f03686ede1 100644
--- a/3rdparty/bgfx/examples/26-occlusion/occlusion.cpp
+++ b/3rdparty/bgfx/examples/26-occlusion/occlusion.cpp
@@ -181,13 +181,10 @@ class ExampleOcclusion : public entry::AppI
float tmp[16];
bx::mtxMul(tmp, view, viewHead);
- float proj[16];
- bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 10000.0f);
-
- bgfx::setViewTransform(0, tmp, proj);
+ bgfx::setViewTransform(0, tmp, hmd->eye[0].projection);
bgfx::setViewRect(0, 0, 0, hmd->width, hmd->height);
- bgfx::setViewTransform(1, tmp, proj);
+ bgfx::setViewTransform(1, tmp, hmd->eye[1].projection);
bgfx::setViewRect(1, 0, 0, hmd->width, hmd->height);
}
else
diff --git a/3rdparty/bgfx/examples/27-terrain/terrain.cpp b/3rdparty/bgfx/examples/27-terrain/terrain.cpp
index 74d88ac350d..0f50be2d4b3 100644
--- a/3rdparty/bgfx/examples/27-terrain/terrain.cpp
+++ b/3rdparty/bgfx/examples/27-terrain/terrain.cpp
@@ -12,8 +12,6 @@
#include <bx/debug.h>
#include <bx/fpumath.h>
-static float s_texelHalf = 0.0f;
-static bool s_originBottomLeft = false;
static uint32_t s_terrainSize = 256;
struct PosTexCoord0Vertex
@@ -94,9 +92,6 @@ class ExampleTerrain : public entry::AppI
imguiCreate();
m_timeOffset = bx::getHPCounter();
- const bgfx::RendererType::Enum renderer = bgfx::getRendererType();
- s_texelHalf = bgfx::RendererType::Direct3D9 == renderer ? 0.5f : 0.0f;
- s_originBottomLeft = bgfx::RendererType::OpenGL == renderer || bgfx::RendererType::OpenGLES == renderer;
m_vbh.idx = bgfx::invalidHandle;
m_ibh.idx = bgfx::invalidHandle;
@@ -463,7 +458,7 @@ class ExampleTerrain : public entry::AppI
bgfx::setViewRect(0, 0, 0, m_width, m_height);
cameraGetViewMtx(m_viewMtx);
- bx::mtxProj(m_projMtx, 60.0f, float(m_width) / float(m_height), 0.1f, 2000.0f, s_originBottomLeft);
+ bx::mtxProj(m_projMtx, 60.0f, float(m_width) / float(m_height), 0.1f, 2000.0f);
bgfx::setViewTransform(0, m_viewMtx, m_projMtx);
bgfx::setTransform(m_terrain.m_transform);
diff --git a/3rdparty/bgfx/include/bgfx/bgfx.h b/3rdparty/bgfx/include/bgfx/bgfx.h
index 28c232d5c7d..eda902ce2f8 100644
--- a/3rdparty/bgfx/include/bgfx/bgfx.h
+++ b/3rdparty/bgfx/include/bgfx/bgfx.h
@@ -499,6 +499,8 @@ namespace bgfx
uint8_t numGPUs; //!< Number of enumerated GPUs.
uint16_t vendorId; //!< Selected GPU vendor id.
uint16_t deviceId; //!< Selected GPU device id.
+ bool homogeneousDepth; //!< True when NDC depth is in [-1, 1] range.
+ bool originBottomLeft; //!< True when NDC origin is at bottom left.
/// GPU info.
///
@@ -613,6 +615,7 @@ namespace bgfx
float translation[3]; //!< Eye translation.
float fov[4]; //!< Field of view (up, down, left, right).
float viewOffset[3]; //!< Eye view matrix translation adjustment.
+ float projection[16]; //!< Eye projection matrix
float pixelsPerTanAngle[2]; //!<
};
@@ -1912,7 +1915,7 @@ namespace bgfx
///
void setViewRect(uint8_t _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height);
- /// @attention C99 equivalent is `bgfx_set_view_rect_auto`.
+ /// @attention C99 equivalent is `bgfx_set_view_rect_auto`.
///
void setViewRect(uint8_t _id, uint16_t _x, uint16_t _y, BackbufferRatio::Enum _ratio);
diff --git a/3rdparty/bgfx/include/bgfx/c99/bgfx.h b/3rdparty/bgfx/include/bgfx/c99/bgfx.h
index 736ac51f132..92793335336 100644
--- a/3rdparty/bgfx/include/bgfx/c99/bgfx.h
+++ b/3rdparty/bgfx/include/bgfx/c99/bgfx.h
@@ -393,6 +393,8 @@ typedef struct bgfx_caps
uint16_t maxViews;
uint8_t maxFBAttachments;
uint8_t numGPUs;
+ bool homogeneousDepth;
+ bool originBottomLeft;
uint16_t vendorId;
uint16_t deviceId;
diff --git a/3rdparty/bgfx/scripts/genie.lua b/3rdparty/bgfx/scripts/genie.lua
index 5ae3b4f73f1..3cf7e9b4b76 100644
--- a/3rdparty/bgfx/scripts/genie.lua
+++ b/3rdparty/bgfx/scripts/genie.lua
@@ -173,47 +173,14 @@ function exampleProject(_name)
end
if _OPTIONS["with-ovr"] then
- links {
- "winmm",
- "ws2_32",
- }
-
- -- Check for LibOVR 5.0+
- if os.isdir(path.join(os.getenv("OVR_DIR"), "LibOVR/Lib/Windows/Win32/Debug/VS2012")) then
-
- configuration { "x32", "Debug" }
- libdirs { path.join("$(OVR_DIR)/LibOVR/Lib/Windows/Win32/Debug", _ACTION) }
-
- configuration { "x32", "Release" }
- libdirs { path.join("$(OVR_DIR)/LibOVR/Lib/Windows/Win32/Release", _ACTION) }
-
- configuration { "x64", "Debug" }
- libdirs { path.join("$(OVR_DIR)/LibOVR/Lib/Windows/x64/Debug", _ACTION) }
-
- configuration { "x64", "Release" }
- libdirs { path.join("$(OVR_DIR)/LibOVR/Lib/Windows/x64/Release", _ACTION) }
+ configuration { "x32" }
+ libdirs { path.join("$(OVR_DIR)/LibOVR/Lib/Windows/Win32/Release", _ACTION) }
- configuration { "x32 or x64" }
- links { "libovr" }
- else
- configuration { "x32" }
- libdirs { path.join("$(OVR_DIR)/LibOVR/Lib/Win32", _ACTION) }
+ configuration { "x64" }
+ libdirs { path.join("$(OVR_DIR)/LibOVR/Lib/Windows/x64/Release", _ACTION) }
- configuration { "x64" }
- libdirs { path.join("$(OVR_DIR)/LibOVR/Lib/x64", _ACTION) }
-
- configuration { "x32", "Debug" }
- links { "libovrd" }
-
- configuration { "x32", "Release" }
- links { "libovr" }
-
- configuration { "x64", "Debug" }
- links { "libovr64d" }
-
- configuration { "x64", "Release" }
- links { "libovr64" }
- end
+ configuration { "x32 or x64" }
+ links { "libovr" }
configuration {}
end
diff --git a/3rdparty/bgfx/src/amalgamated.cpp b/3rdparty/bgfx/src/amalgamated.cpp
index d61f06845cd..dc6c8f6cd50 100644
--- a/3rdparty/bgfx/src/amalgamated.cpp
+++ b/3rdparty/bgfx/src/amalgamated.cpp
@@ -9,8 +9,8 @@
#include "glcontext_ppapi.cpp"
#include "glcontext_wgl.cpp"
#include "image.cpp"
-#include "ovr.cpp"
-#include "renderdoc.cpp"
+#include "hmd_ovr.cpp"
+#include "debug_renderdoc.cpp"
#include "renderer_d3d9.cpp"
#include "renderer_d3d11.cpp"
#include "renderer_d3d12.cpp"
diff --git a/3rdparty/bgfx/src/bgfx.cpp b/3rdparty/bgfx/src/bgfx.cpp
index 3a839c82815..3c91a05e5a5 100644
--- a/3rdparty/bgfx/src/bgfx.cpp
+++ b/3rdparty/bgfx/src/bgfx.cpp
@@ -1151,6 +1151,10 @@ namespace bgfx
}
BX_TRACE("Max FB attachments: %d", g_caps.maxFBAttachments);
+ BX_TRACE("NDC depth [%d, 1], origin %s left."
+ , g_caps.homogeneousDepth ? -1 : 0
+ , g_caps.originBottomLeft ? "bottom" : "top"
+ );
}
TextureFormat::Enum getViableTextureFormat(const ImageContainer& _imageContainer)
diff --git a/3rdparty/bgfx/src/bgfx_shader.sh b/3rdparty/bgfx/src/bgfx_shader.sh
index 3a1c669f321..099681b0449 100644
--- a/3rdparty/bgfx/src/bgfx_shader.sh
+++ b/3rdparty/bgfx/src/bgfx_shader.sh
@@ -88,6 +88,50 @@ struct BgfxSampler2D
Texture2D m_texture;
};
+struct BgfxISampler2D
+{
+ Texture2D<ivec4> m_texture;
+};
+
+struct BgfxUSampler2D
+{
+ Texture2D<uvec4> m_texture;
+};
+
+struct BgfxSampler2DShadow
+{
+ SamplerComparisonState m_sampler;
+ Texture2D m_texture;
+};
+
+struct BgfxSampler3D
+{
+ SamplerState m_sampler;
+ Texture3D m_texture;
+};
+
+struct BgfxISampler3D
+{
+ Texture3D<ivec4> m_texture;
+};
+
+struct BgfxUSampler3D
+{
+ Texture3D<uvec4> m_texture;
+};
+
+struct BgfxSamplerCube
+{
+ SamplerState m_sampler;
+ TextureCube m_texture;
+};
+
+struct BgfxSampler2DMS
+{
+ SamplerState m_sampler;
+ Texture2DMS<vec4> m_texture;
+};
+
vec4 bgfxTexture2D(BgfxSampler2D _sampler, vec2 _coord)
{
return _sampler.m_texture.Sample(_sampler.m_sampler, _coord);
@@ -110,18 +154,6 @@ vec4 bgfxTexture2DProj(BgfxSampler2D _sampler, vec4 _coord)
return _sampler.m_texture.Sample(_sampler.m_sampler, coord);
}
-struct BgfxSampler2DMS
-{
- SamplerState m_sampler;
- Texture2DMS m_texture;
-};
-
-struct BgfxSampler2DShadow
-{
- SamplerComparisonState m_sampler;
- Texture2D m_texture;
-};
-
float bgfxShadow2D(BgfxSampler2DShadow _sampler, vec3 _coord)
{
return _sampler.m_texture.SampleCmpLevelZero(_sampler.m_sampler, _coord.xy, _coord.z);
@@ -133,22 +165,6 @@ float bgfxShadow2DProj(BgfxSampler2DShadow _sampler, vec4 _coord)
return _sampler.m_texture.SampleCmpLevelZero(_sampler.m_sampler, coord.xy, coord.z);
}
-struct BgfxSampler3D
-{
- SamplerState m_sampler;
- Texture3D m_texture;
-};
-
-struct BgfxISampler3D
-{
- Texture3D<ivec4> m_texture;
-};
-
-struct BgfxUSampler3D
-{
- Texture3D<uvec4> m_texture;
-};
-
vec4 bgfxTexture3D(BgfxSampler3D _sampler, vec3 _coord)
{
return _sampler.m_texture.Sample(_sampler.m_sampler, _coord);
@@ -173,12 +189,6 @@ uvec4 bgfxTexture3D(BgfxUSampler3D _sampler, vec3 _coord)
return _sampler.m_texture.Load(uvec4(_coord * size, 0) );
}
-struct BgfxSamplerCube
-{
- SamplerState m_sampler;
- TextureCube m_texture;
-};
-
vec4 bgfxTextureCube(BgfxSamplerCube _sampler, vec3 _coord)
{
return _sampler.m_texture.Sample(_sampler.m_sampler, _coord);
@@ -194,6 +204,16 @@ vec4 bgfxTexelFetch(BgfxSampler2D _sampler, ivec2 _coord, int _lod)
return _sampler.m_texture.Load(ivec3(_coord, _lod) );
}
+ivec4 bgfxTexelFetch(BgfxISampler2D _sampler, ivec2 _coord, int _lod)
+{
+ return _sampler.m_texture.Load(ivec3(_coord, _lod) );
+}
+
+uvec4 bgfxTexelFetch(BgfxUSampler2D _sampler, ivec2 _coord, int _lod)
+{
+ return _sampler.m_texture.Load(ivec3(_coord, _lod) );
+}
+
vec4 bgfxTexelFetch(BgfxSampler2DMS _sampler, ivec2 _coord, int _sampleIdx)
{
return _sampler.m_texture.Load(_coord, _sampleIdx);
@@ -208,6 +228,12 @@ vec4 bgfxTexelFetch(BgfxSampler3D _sampler, ivec3 _coord, int _lod)
uniform SamplerState _name ## Sampler : register(s[_reg]); \
uniform Texture2D _name ## Texture : register(t[_reg]); \
static BgfxSampler2D _name = { _name ## Sampler, _name ## Texture }
+# define ISAMPLER2D(_name, _reg) \
+ uniform Texture2D<ivec4> _name ## Texture : register(t[_reg]); \
+ static BgfxISampler2D _name = { _name ## Texture }
+# define USAMPLER2D(_name, _reg) \
+ uniform Texture2D<uvec4> _name ## Texture : register(t[_reg]); \
+ static BgfxUSampler2D _name = { _name ## Texture }
# define sampler2D BgfxSampler2D
# define texture2D(_sampler, _coord) bgfxTexture2D(_sampler, _coord)
# define texture2DLod(_sampler, _coord, _level) bgfxTexture2DLod(_sampler, _coord, _level)
@@ -364,8 +390,12 @@ vec4 mod(vec4 _a, vec4 _b) { return _a - _b * floor(_a / _b); }
# define SAMPLER2DSHADOW(_name, _reg) uniform sampler2DShadow _name
# if BGFX_SHADER_LANGUAGE_GLSL >= 130
+# define ISAMPLER2D(_name, _reg) uniform isampler2D _name
+# define USAMPLER2D(_name, _reg) uniform usampler2D _name
# define ISAMPLER3D(_name, _reg) uniform isampler3D _name
# define USAMPLER3D(_name, _reg) uniform usampler3D _name
+ivec4 texture2D(isampler2D _sampler, vec2 _coord) { return texture(_sampler, _coord); }
+uvec4 texture2D(usampler2D _sampler, vec2 _coord) { return texture(_sampler, _coord); }
ivec4 texture3D(isampler3D _sampler, vec3 _coord) { return texture(_sampler, _coord); }
uvec4 texture3D(usampler3D _sampler, vec3 _coord) { return texture(_sampler, _coord); }
# endif // BGFX_SHADER_LANGUAGE_GLSL >= 130
diff --git a/3rdparty/bgfx/src/renderdoc.cpp b/3rdparty/bgfx/src/debug_renderdoc.cpp
index 0cb7be99d64..0cb7be99d64 100644
--- a/3rdparty/bgfx/src/renderdoc.cpp
+++ b/3rdparty/bgfx/src/debug_renderdoc.cpp
diff --git a/3rdparty/bgfx/src/renderdoc.h b/3rdparty/bgfx/src/debug_renderdoc.h
index 803805ea581..803805ea581 100644
--- a/3rdparty/bgfx/src/renderdoc.h
+++ b/3rdparty/bgfx/src/debug_renderdoc.h
diff --git a/3rdparty/bgfx/src/glimports.h b/3rdparty/bgfx/src/glimports.h
index f288a6a3597..7e110f06928 100644
--- a/3rdparty/bgfx/src/glimports.h
+++ b/3rdparty/bgfx/src/glimports.h
@@ -515,6 +515,7 @@ GL_IMPORT_OES__(true, PFNGLBINDVERTEXARRAYPROC, glBindVertexA
GL_IMPORT_OES__(true, PFNGLDELETEVERTEXARRAYSPROC, glDeleteVertexArrays);
GL_IMPORT_OES__(true, PFNGLGENVERTEXARRAYSPROC, glGenVertexArrays);
+GL_IMPORT_____x(true, PFNGLCLIPCONTROLPROC, glClipControl);
GL_IMPORT_____x(true, PFNGLENABLEIPROC, glEnablei);
GL_IMPORT_____x(true, PFNGLDISABLEIPROC, glDisablei);
GL_IMPORT_____x(true, PFNGLBLENDEQUATIONIPROC, glBlendEquationi);
@@ -556,6 +557,7 @@ GL_IMPORT_NV___(true, PFNGLQUERYCOUNTERPROC, glQueryCounte
GL_IMPORT (true, PFNGLINVALIDATEFRAMEBUFFERPROC, glInvalidateFramebuffer, glDiscardFramebufferEXT);
# elif !BGFX_USE_GL_DYNAMIC_LIB
+GL_IMPORT______(true, PFNGLCLIPCONTROLPROC, glClipControl);
GL_IMPORT______(true, PFNGLGETSTRINGIPROC, glGetStringi);
GL_IMPORT______(true, PFNGLTEXIMAGE3DPROC, glTexImage3D);
diff --git a/3rdparty/bgfx/src/hmd_ovr.cpp b/3rdparty/bgfx/src/hmd_ovr.cpp
new file mode 100644
index 00000000000..e8d465e4259
--- /dev/null
+++ b/3rdparty/bgfx/src/hmd_ovr.cpp
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2011-2016 Branimir Karadzic. All rights reserved.
+ * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
+ */
+
+#include "hmd_ovr.h"
+
+#if BGFX_CONFIG_USE_OVR
+
+namespace bgfx
+{
+ OVR::OVR()
+ : m_hmd(NULL)
+ , m_isenabled(false)
+ , m_mirror(NULL)
+ , m_hmdFrameReady(-1)
+ , m_frameIndex(0)
+ , m_sensorSampleTime(0)
+ {
+ memset(m_eyeBuffers, 0, sizeof(m_eyeBuffers));
+ }
+
+ OVR::~OVR()
+ {
+ BX_CHECK(NULL == m_hmd, "OVR not shutdown properly.");
+ }
+
+ void OVR::init()
+ {
+ ovrResult initialized = ovr_Initialize(NULL);
+ ovrGraphicsLuid luid;
+
+ BX_WARN(initialized == ovrSuccess, "Unable to create OVR device.");
+
+ if (initialized != ovrSuccess)
+ {
+ return;
+ }
+
+ initialized = ovr_Create(&m_hmd, &luid);
+ if (initialized != ovrSuccess)
+ {
+ BX_WARN(initialized == ovrSuccess, "Unable to create OVR device.");
+ return;
+ }
+
+ m_hmdDesc = ovr_GetHmdDesc(m_hmd);
+
+ BX_TRACE("HMD: %s, %s, firmware: %d.%d"
+ , m_hmdDesc.ProductName
+ , m_hmdDesc.Manufacturer
+ , m_hmdDesc.FirmwareMajor
+ , m_hmdDesc.FirmwareMinor
+ );
+
+ ovrSizei sizeL = ovr_GetFovTextureSize(m_hmd, ovrEye_Left, m_hmdDesc.DefaultEyeFov[0], 1.0f);
+ ovrSizei sizeR = ovr_GetFovTextureSize(m_hmd, ovrEye_Right, m_hmdDesc.DefaultEyeFov[1], 1.0f);
+ m_hmdSize.w = sizeL.w + sizeR.w;
+ m_hmdSize.h = bx::uint32_max(sizeL.h, sizeR.h);
+ }
+
+ void OVR::shutdown()
+ {
+ BX_CHECK(!m_isenabled, "HMD not disabled.");
+
+ for (int i = 0; i < 2; i++)
+ {
+ if (m_eyeBuffers[i])
+ {
+ m_eyeBuffers[i]->destroy(m_hmd);
+ BX_DELETE(g_allocator, m_eyeBuffers[i]);
+ }
+ }
+
+ if (m_mirror)
+ {
+ m_mirror->destroy(m_hmd);
+ BX_DELETE(g_allocator, m_mirror);
+ }
+
+ ovr_Destroy(m_hmd);
+ m_hmd = NULL;
+ ovr_Shutdown();
+ }
+
+ void OVR::getViewport(uint8_t _eye, Rect* _viewport)
+ {
+ _viewport->m_x = 0;
+ _viewport->m_y = 0;
+ _viewport->m_width = m_eyeBuffers[_eye]->m_eyeTextureSize.w;
+ _viewport->m_height = m_eyeBuffers[_eye]->m_eyeTextureSize.h;
+ }
+
+ void OVR::renderEyeStart(uint8_t _eye)
+ {
+ m_eyeBuffers[_eye]->onRender(m_hmd);
+ }
+
+ bool OVR::postReset()
+ {
+ if (NULL == m_hmd)
+ {
+ return false;
+ }
+
+ for (int eyeIdx = 0; eyeIdx < ovrEye_Count; eyeIdx++)
+ {
+ m_erd[eyeIdx] = ovr_GetRenderDesc(m_hmd, (ovrEyeType)eyeIdx, m_hmdDesc.DefaultEyeFov[eyeIdx]);
+ }
+
+ m_isenabled = true;
+
+ return true;
+ }
+
+ void OVR::preReset()
+ {
+ if (m_isenabled)
+ {
+ // on window resize this will recreate the mirror texture in ovrPostReset
+ m_mirror->destroy(m_hmd);
+ BX_DELETE(g_allocator, m_mirror);
+ m_mirror = NULL;
+ m_isenabled = false;
+ }
+ }
+
+ void OVR::commitEye(uint8_t _eye)
+ {
+ if (m_isenabled)
+ {
+ m_hmdFrameReady = ovr_CommitTextureSwapChain(m_hmd, m_eyeBuffers[_eye]->m_swapTextureChain);
+ }
+ }
+
+ bool OVR::swap(HMD& _hmd, bool originBottomLeft)
+ {
+ _hmd.flags = BGFX_HMD_NONE;
+
+ if (NULL != m_hmd)
+ {
+ _hmd.flags |= BGFX_HMD_DEVICE_RESOLUTION;
+ _hmd.deviceWidth = m_hmdDesc.Resolution.w;
+ _hmd.deviceHeight = m_hmdDesc.Resolution.h;
+ }
+
+ if (!m_isenabled || !OVR_SUCCESS(m_hmdFrameReady))
+ {
+ return false;
+ }
+
+ _hmd.flags |= BGFX_HMD_RENDERING;
+
+ // finish frame for current eye
+ ovrViewScaleDesc viewScaleDesc;
+ viewScaleDesc.HmdSpaceToWorldScaleInMeters = 1.0f;
+ viewScaleDesc.HmdToEyeOffset[0] = m_hmdToEyeOffset[0];
+ viewScaleDesc.HmdToEyeOffset[1] = m_hmdToEyeOffset[1];
+
+ // create the main eye layer
+ ovrLayerEyeFov eyeLayer;
+ eyeLayer.Header.Type = ovrLayerType_EyeFov;
+ eyeLayer.Header.Flags = originBottomLeft ? ovrLayerFlag_TextureOriginAtBottomLeft : 0;
+
+ for (int eye = 0; eye < ovrEye_Count; eye++)
+ {
+ eyeLayer.ColorTexture[eye] = m_eyeBuffers[eye]->m_swapTextureChain;
+ eyeLayer.Viewport[eye].Pos.x = 0;
+ eyeLayer.Viewport[eye].Pos.y = 0;
+ eyeLayer.Viewport[eye].Size.w = m_eyeBuffers[eye]->m_eyeTextureSize.w;
+ eyeLayer.Viewport[eye].Size.h = m_eyeBuffers[eye]->m_eyeTextureSize.h;
+ eyeLayer.Fov[eye] = m_hmdDesc.DefaultEyeFov[eye];
+ eyeLayer.RenderPose[eye] = m_pose[eye];
+ eyeLayer.SensorSampleTime = m_sensorSampleTime;
+ }
+
+ // append all the layers to global list
+ ovrLayerHeader* layerList = &eyeLayer.Header;
+
+ ovr_SubmitFrame(m_hmd, m_frameIndex, NULL, &layerList, 1);
+
+ // perform mirror texture blit right after the entire frame is submitted to HMD
+ m_mirror->blit(m_hmd);
+
+ m_hmdToEyeOffset[0] = m_erd[0].HmdToEyeOffset;
+ m_hmdToEyeOffset[1] = m_erd[1].HmdToEyeOffset;
+
+ ovr_GetEyePoses(m_hmd, m_frameIndex, ovrTrue, m_hmdToEyeOffset, m_pose, &m_sensorSampleTime);
+
+ getEyePose(_hmd);
+
+ return true;
+ }
+
+ void OVR::recenter()
+ {
+ if (NULL != m_hmd)
+ {
+ ovr_RecenterTrackingOrigin(m_hmd);
+ }
+ }
+
+ void OVR::getEyePose(HMD& _hmd)
+ {
+ if (NULL != m_hmd)
+ {
+ for (int ii = 0; ii < 2; ++ii)
+ {
+ const ovrPosef& pose = m_pose[ii];
+ HMD::Eye& eye = _hmd.eye[ii];
+ eye.rotation[0] = pose.Orientation.x;
+ eye.rotation[1] = pose.Orientation.y;
+ eye.rotation[2] = pose.Orientation.z;
+ eye.rotation[3] = pose.Orientation.w;
+ eye.translation[0] = pose.Position.x;
+ eye.translation[1] = pose.Position.y;
+ eye.translation[2] = pose.Position.z;
+
+ const ovrEyeRenderDesc& erd = m_erd[ii];
+ eye.fov[0] = erd.Fov.UpTan;
+ eye.fov[1] = erd.Fov.DownTan;
+ eye.fov[2] = erd.Fov.LeftTan;
+ eye.fov[3] = erd.Fov.RightTan;
+
+ ovrMatrix4f eyeProj = ovrMatrix4f_Projection(m_erd[ii].Fov, 0.01f, 1000.0f, ovrProjection_LeftHanded);
+ for (int jj = 0; jj < 4; ++jj)
+ {
+ for (int kk = 0; kk < 4; ++kk)
+ {
+ eye.projection[4 * jj + kk] = eyeProj.M[kk][jj];
+ }
+ }
+
+ eye.viewOffset[0] = erd.HmdToEyeOffset.x;
+ eye.viewOffset[1] = erd.HmdToEyeOffset.y;
+ eye.viewOffset[2] = erd.HmdToEyeOffset.z;
+
+ eye.pixelsPerTanAngle[0] = erd.PixelsPerTanAngleAtCenter.x;
+ eye.pixelsPerTanAngle[1] = erd.PixelsPerTanAngleAtCenter.y;
+ }
+ }
+
+ _hmd.width = uint16_t(m_hmdSize.w);
+ _hmd.height = uint16_t(m_hmdSize.h);
+ }
+
+} // namespace bgfx
+
+#endif // BGFX_CONFIG_USE_OVR
diff --git a/3rdparty/bgfx/src/ovr.h b/3rdparty/bgfx/src/hmd_ovr.h
index b717d0d47a8..f8d41449514 100644
--- a/3rdparty/bgfx/src/ovr.h
+++ b/3rdparty/bgfx/src/hmd_ovr.h
@@ -14,36 +14,42 @@
# define OVR_VERSION_(_a, _b, _c) (_a * 10000 + _b * 100 + _c)
# define OVR_VERSION OVR_VERSION_(OVR_PRODUCT_VERSION, OVR_MAJOR_VERSION, OVR_MINOR_VERSION)
-# define OVR_VERSION_042 OVR_VERSION_(0, 4, 2)
-# define OVR_VERSION_043 OVR_VERSION_(0, 4, 3)
-# define OVR_VERSION_044 OVR_VERSION_(0, 4, 4)
-# define OVR_VERSION_050 OVR_VERSION_(0, 5, 0)
-# if OVR_VERSION < OVR_VERSION_050
-# include <OVR.h>
-# else
-# include <OVR_CAPI.h>
-# endif // OVR_VERSION < OVR_VERSION_050
+# include <OVR_CAPI.h>
# if BGFX_CONFIG_RENDERER_DIRECT3D11
-# if OVR_VERSION < OVR_VERSION_050
-# define OVR_D3D_VERSION 11
-# include <OVR_D3D.h>
-# else
-# include <OVR_CAPI_D3D.h>
-# endif
+# include <OVR_CAPI_D3D.h>
# endif // BGFX_CONFIG_RENDERER_DIRECT3D11
# if BGFX_CONFIG_RENDERER_OPENGL
-# if OVR_VERSION < OVR_VERSION_050
-# include <OVR_GL.h>
-# else
-# include <OVR_CAPI_GL.h>
-# endif
+# include <OVR_CAPI_GL.h>
# endif // BGFX_CONFIG_RENDERER_OPENGL
namespace bgfx
{
+ // single eye buffer
+ struct OVRBufferI
+ {
+ virtual ~OVRBufferI() {};
+ virtual void onRender(const ovrSession &session) = 0;
+ virtual void destroy(const ovrSession &session) = 0;
+
+ ovrSizei m_eyeTextureSize;
+ ovrTextureSwapChain m_swapTextureChain;
+ };
+
+ // mirrored window output
+ struct OVRMirrorI
+ {
+ virtual ~OVRMirrorI() {};
+ virtual void init(const ovrSession &session, int windowWidth, int windowHeight) = 0;
+ virtual void destroy(const ovrSession &session) = 0;
+ virtual void blit(const ovrSession &session) = 0;
+
+ ovrMirrorTexture m_mirrorTexture;
+ ovrMirrorTextureDesc m_mirrorDesc;
+ };
+
struct OVR
{
OVR();
@@ -59,37 +65,31 @@ namespace bgfx
return m_isenabled;
}
- bool isDebug() const
- {
- return m_debug;
- }
-
void init();
void shutdown();
void getViewport(uint8_t _eye, Rect* _viewport);
- bool postReset(void* _nwh, ovrRenderAPIConfig* _config, bool _debug = false);
- void postReset(const ovrTexture& _texture);
+ void renderEyeStart(uint8_t _eye);
+ bool postReset();
void preReset();
- bool swap(HMD& _hmd);
+ void commitEye(uint8_t _eye);
+ bool swap(HMD& _hmd, bool originBottomLeft);
void recenter();
void getEyePose(HMD& _hmd);
- void getSize(uint32_t& _width, uint32_t& _height) const
- {
- _width = m_rtSize.w;
- _height = m_rtSize.h;
- }
- ovrHmd m_hmd;
- ovrFrameTiming m_timing;
+ ovrSession m_hmd;
+ ovrHmdDesc m_hmdDesc;
ovrEyeRenderDesc m_erd[2];
- ovrRecti m_rect[2];
- ovrPosef m_pose[2];
- ovrTexture m_texture[2];
- ovrSizei m_rtSize;
- bool m_warning;
+ ovrRecti m_rect[2];
+ ovrPosef m_pose[2];
+ ovrVector3f m_hmdToEyeOffset[2];
+ ovrSizei m_hmdSize;
+ ovrResult m_hmdFrameReady;
+ OVRBufferI *m_eyeBuffers[2];
+ OVRMirrorI *m_mirror;
+ long long m_frameIndex;
+ double m_sensorSampleTime;
bool m_isenabled;
- bool m_debug;
};
} // namespace bgfx
@@ -139,7 +139,15 @@ namespace bgfx
_viewport->m_height = 0;
}
- bool swap(HMD& _hmd)
+ void commitEye(uint8_t /*_eye*/)
+ {
+ }
+
+ void renderEyeStart(uint8_t /*_eye*/)
+ {
+ }
+
+ bool swap(HMD& _hmd, bool /*originBottomLeft*/)
{
_hmd.flags = BGFX_HMD_NONE;
getEyePose(_hmd);
@@ -155,12 +163,6 @@ namespace bgfx
_hmd.width = 0;
_hmd.height = 0;
}
-
- void getSize(uint32_t& _width, uint32_t& _height) const
- {
- _width = 0;
- _height = 0;
- }
};
} // namespace bgfx
diff --git a/3rdparty/bgfx/src/ovr.cpp b/3rdparty/bgfx/src/ovr.cpp
deleted file mode 100644
index 5cd62ef3956..00000000000
--- a/3rdparty/bgfx/src/ovr.cpp
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Copyright 2011-2016 Branimir Karadzic. All rights reserved.
- * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
- */
-
-#include "ovr.h"
-
-#if BGFX_CONFIG_USE_OVR
-
-namespace bgfx
-{
-#if OVR_VERSION <= OVR_VERSION_050
-# define OVR_EYE_BUFFER 100
-#else
-# define OVR_EYE_BUFFER 8
-#endif // OVR_VERSION...
-
- OVR::OVR()
- : m_hmd(NULL)
- , m_isenabled(false)
- , m_debug(false)
- {
- }
-
- OVR::~OVR()
- {
- BX_CHECK(NULL == m_hmd, "OVR not shutdown properly.");
- }
-
- void OVR::init()
- {
- bool initialized = !!ovr_Initialize();
- BX_WARN(initialized, "Unable to create OVR device.");
- if (!initialized)
- {
- return;
- }
-
- m_hmd = ovrHmd_Create(0);
- if (NULL == m_hmd)
- {
- m_hmd = ovrHmd_CreateDebug(ovrHmd_DK2);
- BX_WARN(NULL != m_hmd, "Unable to create OVR device.");
- if (NULL == m_hmd)
- {
- return;
- }
- }
-
- BX_TRACE("HMD: %s, %s, firmware: %d.%d"
- , m_hmd->ProductName
- , m_hmd->Manufacturer
- , m_hmd->FirmwareMajor
- , m_hmd->FirmwareMinor
- );
-
- ovrSizei sizeL = ovrHmd_GetFovTextureSize(m_hmd, ovrEye_Left, m_hmd->DefaultEyeFov[0], 1.0f);
- ovrSizei sizeR = ovrHmd_GetFovTextureSize(m_hmd, ovrEye_Right, m_hmd->DefaultEyeFov[1], 1.0f);
- m_rtSize.w = sizeL.w + sizeR.w + OVR_EYE_BUFFER;
- m_rtSize.h = bx::uint32_max(sizeL.h, sizeR.h);
- m_warning = true;
- }
-
- void OVR::shutdown()
- {
- BX_CHECK(!m_isenabled, "HMD not disabled.");
- ovrHmd_Destroy(m_hmd);
- m_hmd = NULL;
- ovr_Shutdown();
- }
-
- void OVR::getViewport(uint8_t _eye, Rect* _viewport)
- {
- _viewport->m_x = _eye * (m_rtSize.w + OVR_EYE_BUFFER + 1)/2;
- _viewport->m_y = 0;
- _viewport->m_width = (m_rtSize.w - OVR_EYE_BUFFER)/2;
- _viewport->m_height = m_rtSize.h;
- }
-
- bool OVR::postReset(void* _nwh, ovrRenderAPIConfig* _config, bool _debug)
- {
- if (_debug)
- {
- switch (_config->Header.API)
- {
-#if BGFX_CONFIG_RENDERER_DIRECT3D11
- case ovrRenderAPI_D3D11:
- {
- ovrD3D11ConfigData* data = (ovrD3D11ConfigData*)_config;
-# if OVR_VERSION > OVR_VERSION_043
- m_rtSize = data->Header.BackBufferSize;
-# else
- m_rtSize = data->Header.RTSize;
-# endif // OVR_VERSION > OVR_VERSION_043
- }
- break;
-#endif // BGFX_CONFIG_RENDERER_DIRECT3D11
-
-#if BGFX_CONFIG_RENDERER_OPENGL
- case ovrRenderAPI_OpenGL:
- {
- ovrGLConfigData* data = (ovrGLConfigData*)_config;
-# if OVR_VERSION > OVR_VERSION_043
- m_rtSize = data->Header.BackBufferSize;
-# else
- m_rtSize = data->Header.RTSize;
-# endif // OVR_VERSION > OVR_VERSION_043
- }
- break;
-#endif // BGFX_CONFIG_RENDERER_OPENGL
-
- case ovrRenderAPI_None:
- default:
- BX_CHECK(false, "You should not be here!");
- break;
- }
-
- m_debug = true;
- return false;
- }
-
- if (NULL == m_hmd)
- {
- return false;
- }
-
- m_isenabled = true;
-
- ovrBool result;
- result = ovrHmd_AttachToWindow(m_hmd, _nwh, NULL, NULL);
- if (!result) { goto ovrError; }
-
- ovrFovPort eyeFov[2] = { m_hmd->DefaultEyeFov[0], m_hmd->DefaultEyeFov[1] };
- result = ovrHmd_ConfigureRendering(m_hmd
- , _config
- , 0
-#if OVR_VERSION < OVR_VERSION_050
- | ovrDistortionCap_Chromatic // permanently enabled >= v5.0
-#endif
- | ovrDistortionCap_Vignette
- | ovrDistortionCap_TimeWarp
- | ovrDistortionCap_Overdrive
- | ovrDistortionCap_NoRestore
- | ovrDistortionCap_HqDistortion
- , eyeFov
- , m_erd
- );
- if (!result) { goto ovrError; }
-
- ovrHmd_SetEnabledCaps(m_hmd
- , 0
- | ovrHmdCap_LowPersistence
- | ovrHmdCap_DynamicPrediction
- );
-
- result = ovrHmd_ConfigureTracking(m_hmd
- , 0
- | ovrTrackingCap_Orientation
- | ovrTrackingCap_MagYawCorrection
- | ovrTrackingCap_Position
- , 0
- );
-
- if (!result)
- {
-ovrError:
- BX_TRACE("Failed to initialize OVR.");
- m_isenabled = false;
- return false;
- }
-
- m_warning = true;
- return true;
- }
-
- void OVR::postReset(const ovrTexture& _texture)
- {
- if (NULL != m_hmd)
- {
- m_texture[0] = _texture;
- m_texture[1] = _texture;
-
- ovrRecti rect;
- rect.Pos.x = 0;
- rect.Pos.y = 0;
- rect.Size.w = (m_rtSize.w - OVR_EYE_BUFFER)/2;
- rect.Size.h = m_rtSize.h;
-
- m_texture[0].Header.RenderViewport = rect;
-
- rect.Pos.x += rect.Size.w + OVR_EYE_BUFFER;
- m_texture[1].Header.RenderViewport = rect;
-
- m_timing = ovrHmd_BeginFrame(m_hmd, 0);
-#if OVR_VERSION > OVR_VERSION_042
- m_pose[0] = ovrHmd_GetHmdPosePerEye(m_hmd, ovrEye_Left);
- m_pose[1] = ovrHmd_GetHmdPosePerEye(m_hmd, ovrEye_Right);
-#else
- m_pose[0] = ovrHmd_GetEyePose(m_hmd, ovrEye_Left);
- m_pose[1] = ovrHmd_GetEyePose(m_hmd, ovrEye_Right);
-#endif // OVR_VERSION > OVR_VERSION_042
- }
- }
-
- void OVR::preReset()
- {
- if (m_isenabled)
- {
- ovrHmd_EndFrame(m_hmd, m_pose, m_texture);
- ovrHmd_AttachToWindow(m_hmd, NULL, NULL, NULL);
- ovrHmd_ConfigureRendering(m_hmd, NULL, 0, NULL, NULL);
- m_isenabled = false;
- }
-
- m_debug = false;
- }
-
- bool OVR::swap(HMD& _hmd)
- {
- _hmd.flags = BGFX_HMD_NONE;
-
- if (NULL != m_hmd)
- {
- _hmd.flags |= BGFX_HMD_DEVICE_RESOLUTION;
- _hmd.deviceWidth = m_hmd->Resolution.w;
- _hmd.deviceHeight = m_hmd->Resolution.h;
- }
-
- if (!m_isenabled)
- {
- return false;
- }
-
- _hmd.flags |= BGFX_HMD_RENDERING;
- ovrHmd_EndFrame(m_hmd, m_pose, m_texture);
-
- if (m_warning)
- {
- m_warning = !ovrHmd_DismissHSWDisplay(m_hmd);
- }
-
- m_timing = ovrHmd_BeginFrame(m_hmd, 0);
-
-#if OVR_VERSION > OVR_VERSION_042
- m_pose[0] = ovrHmd_GetHmdPosePerEye(m_hmd, ovrEye_Left);
- m_pose[1] = ovrHmd_GetHmdPosePerEye(m_hmd, ovrEye_Right);
-#else
- m_pose[0] = ovrHmd_GetEyePose(m_hmd, ovrEye_Left);
- m_pose[1] = ovrHmd_GetEyePose(m_hmd, ovrEye_Right);
-#endif // OVR_VERSION > OVR_VERSION_042
-
- getEyePose(_hmd);
-
- return true;
- }
-
- void OVR::recenter()
- {
- if (NULL != m_hmd)
- {
- ovrHmd_RecenterPose(m_hmd);
- }
- }
-
- void OVR::getEyePose(HMD& _hmd)
- {
- if (NULL != m_hmd)
- {
- for (int ii = 0; ii < 2; ++ii)
- {
- const ovrPosef& pose = m_pose[ii];
- HMD::Eye& eye = _hmd.eye[ii];
- eye.rotation[0] = pose.Orientation.x;
- eye.rotation[1] = pose.Orientation.y;
- eye.rotation[2] = pose.Orientation.z;
- eye.rotation[3] = pose.Orientation.w;
- eye.translation[0] = pose.Position.x;
- eye.translation[1] = pose.Position.y;
- eye.translation[2] = pose.Position.z;
-
- const ovrEyeRenderDesc& erd = m_erd[ii];
- eye.fov[0] = erd.Fov.UpTan;
- eye.fov[1] = erd.Fov.DownTan;
- eye.fov[2] = erd.Fov.LeftTan;
- eye.fov[3] = erd.Fov.RightTan;
-#if OVR_VERSION > OVR_VERSION_042
- eye.viewOffset[0] = erd.HmdToEyeViewOffset.x;
- eye.viewOffset[1] = erd.HmdToEyeViewOffset.y;
- eye.viewOffset[2] = erd.HmdToEyeViewOffset.z;
-#else
- eye.viewOffset[0] = erd.ViewAdjust.x;
- eye.viewOffset[1] = erd.ViewAdjust.y;
- eye.viewOffset[2] = erd.ViewAdjust.z;
-#endif // OVR_VERSION > OVR_VERSION_042
- eye.pixelsPerTanAngle[0] = erd.PixelsPerTanAngleAtCenter.x;
- eye.pixelsPerTanAngle[1] = erd.PixelsPerTanAngleAtCenter.y;
- }
- }
- else
- {
- for (int ii = 0; ii < 2; ++ii)
- {
- _hmd.eye[ii].rotation[0] = 0.0f;
- _hmd.eye[ii].rotation[1] = 0.0f;
- _hmd.eye[ii].rotation[2] = 0.0f;
- _hmd.eye[ii].rotation[3] = 1.0f;
- _hmd.eye[ii].translation[0] = 0.0f;
- _hmd.eye[ii].translation[1] = 0.0f;
- _hmd.eye[ii].translation[2] = 0.0f;
- _hmd.eye[ii].fov[0] = 1.32928634f;
- _hmd.eye[ii].fov[1] = 1.32928634f;
- _hmd.eye[ii].fov[2] = 0 == ii ? 1.05865765f : 1.09236801f;
- _hmd.eye[ii].fov[3] = 0 == ii ? 1.09236801f : 1.05865765f;
- _hmd.eye[ii].viewOffset[0] = 0 == ii ? 0.0355070010f : -0.0375000015f;
- _hmd.eye[ii].viewOffset[1] = 0.0f;
- _hmd.eye[ii].viewOffset[2] = 0 == ii ? 0.00150949787f : -0.00150949787f;
- _hmd.eye[ii].pixelsPerTanAngle[0] = 1;
- _hmd.eye[ii].pixelsPerTanAngle[1] = 1;
- }
- }
-
- _hmd.width = uint16_t(m_rtSize.w);
- _hmd.height = uint16_t(m_rtSize.h);
- }
-
-} // namespace bgfx
-
-#endif // BGFX_CONFIG_USE_OVR
diff --git a/3rdparty/bgfx/src/renderer_d3d11.cpp b/3rdparty/bgfx/src/renderer_d3d11.cpp
index cd794028c30..6d21d13612d 100644
--- a/3rdparty/bgfx/src/renderer_d3d11.cpp
+++ b/3rdparty/bgfx/src/renderer_d3d11.cpp
@@ -601,6 +601,170 @@ namespace bgfx { namespace d3d11
static PFN_GET_DEBUG_INTERFACE1 DXGIGetDebugInterface1;
#endif // USE_D3D11_DYNAMIC_LIB
+
+#if BGFX_CONFIG_USE_OVR
+
+#include <tinystl/vector.h>
+
+ // Oculus Rift eye buffer
+ struct OVRBufferDX11 : public OVRBufferI
+ {
+ OVRBufferDX11(const ovrSession& session, int eyeIdx, ID3D11Device* d3dDevice, ID3D11DeviceContext* d3dCtx)
+ {
+ m_d3dDevice = d3dDevice;
+ m_d3dContext = d3dCtx;
+ ovrHmdDesc hmdDesc = ovr_GetHmdDesc(session);
+ m_eyeTextureSize = ovr_GetFovTextureSize(session, (ovrEyeType)eyeIdx, hmdDesc.DefaultEyeFov[eyeIdx], 1.0f);
+
+ ovrTextureSwapChainDesc desc = {};
+ desc.Type = ovrTexture_2D;
+ desc.ArraySize = 1;
+ desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
+ desc.Width = m_eyeTextureSize.w;
+ desc.Height = m_eyeTextureSize.h;
+ desc.MipLevels = 1;
+ desc.SampleCount = 1;
+ desc.MiscFlags = ovrTextureMisc_DX_Typeless;
+ desc.BindFlags = ovrTextureBind_DX_RenderTarget;
+ desc.StaticImage = ovrFalse;
+
+ ovrResult result = ovr_CreateTextureSwapChainDX(session, d3dDevice, &desc, &m_swapTextureChain);
+
+ if (!OVR_SUCCESS(result))
+ {
+ BX_CHECK(false, "Could not create D3D11 OVR swap texture");
+ }
+
+ int textureCount = 0;
+ ovr_GetTextureSwapChainLength(session, m_swapTextureChain, &textureCount);
+
+ for (int i = 0; i < textureCount; ++i)
+ {
+ ID3D11Texture2D* tex = NULL;
+ ovr_GetTextureSwapChainBufferDX(session, m_swapTextureChain, i, IID_PPV_ARGS(&tex));
+ D3D11_RENDER_TARGET_VIEW_DESC rtvd = {};
+ rtvd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ rtvd.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+
+ ID3D11RenderTargetView* rtv;
+ DX_CHECK(d3dDevice->CreateRenderTargetView(tex, &rtvd, &rtv));
+ m_eyeRtv.push_back(rtv);
+ tex->Release();
+ }
+
+ // setup depth buffer
+ D3D11_TEXTURE2D_DESC dbDesc;
+ dbDesc.Width = m_eyeTextureSize.w;
+ dbDesc.Height = m_eyeTextureSize.h;
+ dbDesc.MipLevels = 1;
+ dbDesc.ArraySize = 1;
+ dbDesc.Format = DXGI_FORMAT_D32_FLOAT;
+ dbDesc.SampleDesc.Count = 1;
+ dbDesc.SampleDesc.Quality = 0;
+ dbDesc.Usage = D3D11_USAGE_DEFAULT;
+ dbDesc.CPUAccessFlags = 0;
+ dbDesc.MiscFlags = 0;
+ dbDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
+ ID3D11Texture2D* tex;
+ DX_CHECK(d3dDevice->CreateTexture2D(&dbDesc, NULL, &tex));
+ DX_CHECK(d3dDevice->CreateDepthStencilView(tex, NULL, &m_depthBuffer));
+ tex->Release();
+ }
+
+ void onRender(const ovrSession& session)
+ {
+ // Clear and set up rendertarget
+ int texIndex = 0;
+ ovr_GetTextureSwapChainCurrentIndex(session, m_swapTextureChain, &texIndex);
+
+ float black[] = { 0.f, 0.f, 0.f, 0.f }; // Important that alpha=0, if want pixels to be transparent, for manual layers
+ m_d3dContext->OMSetRenderTargets(1, &m_eyeRtv[texIndex], m_depthBuffer);
+ m_d3dContext->ClearRenderTargetView(m_eyeRtv[texIndex], black);
+ m_d3dContext->ClearDepthStencilView(m_depthBuffer, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
+
+ D3D11_VIEWPORT D3Dvp;
+ D3Dvp.TopLeftX = 0;
+ D3Dvp.TopLeftY = 0;
+ D3Dvp.Width = (FLOAT)m_eyeTextureSize.w;
+ D3Dvp.Height = (FLOAT)m_eyeTextureSize.h;
+ D3Dvp.MinDepth = 0;
+ D3Dvp.MaxDepth = 1;
+ m_d3dContext->RSSetViewports(1, &D3Dvp);
+ }
+
+ void destroy(const ovrSession& session)
+ {
+ for (size_t i = 0; i < m_eyeRtv.size(); ++i)
+ {
+ m_eyeRtv[i]->Release();
+ }
+
+ ovr_DestroyTextureSwapChain(session, m_swapTextureChain);
+ m_depthBuffer->Release();
+ }
+
+ ID3D11Device* m_d3dDevice;
+ ID3D11DeviceContext* m_d3dContext;
+ stl::vector<ID3D11RenderTargetView *> m_eyeRtv;
+ ID3D11DepthStencilView* m_depthBuffer;
+ };
+
+ // Oculus Rift mirror
+ struct OVRMirrorDX11 : public OVRMirrorI
+ {
+ OVRMirrorDX11(ID3D11Device* d3dDevice,
+ ID3D11DeviceContext* d3dCtx,
+ IDXGISwapChain* d3dSc) : m_d3dDevice(d3dDevice)
+ , m_d3dContext(d3dCtx)
+ , m_d3dSwapChain(d3dSc)
+ {
+ }
+
+ void init(const ovrSession& session, int windowWidth, int windowHeight)
+ {
+ m_mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
+ m_mirrorDesc.Width = windowWidth;
+ m_mirrorDesc.Height = windowHeight;
+ ovrResult result = ovr_CreateMirrorTextureDX(session, m_d3dDevice, &m_mirrorDesc, &m_mirrorTexture);
+
+ if (!OVR_SUCCESS(result))
+ {
+ BX_CHECK(false, "Could not create D3D11 OVR mirror texture");
+ }
+ }
+
+ void destroy(const ovrSession& session)
+ {
+ if (!m_mirrorTexture)
+ return;
+
+ ovr_DestroyMirrorTexture(session, m_mirrorTexture);
+ m_mirrorTexture = NULL;
+ }
+
+ void blit(const ovrSession& session)
+ {
+ if (!m_mirrorTexture)
+ return;
+
+ ID3D11Texture2D* tex = NULL;
+ ovr_GetMirrorTextureBufferDX(session, m_mirrorTexture, IID_PPV_ARGS(&tex));
+ ID3D11Texture2D* backBuffer;
+ DX_CHECK(m_d3dSwapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBuffer));
+
+ m_d3dContext->CopyResource(backBuffer, tex);
+ DX_CHECK(m_d3dSwapChain->Present(0, 0));
+
+ tex->Release();
+ backBuffer->Release();
+ }
+
+ ID3D11Device* m_d3dDevice;
+ ID3D11DeviceContext* m_d3dContext;
+ IDXGISwapChain* m_d3dSwapChain;
+ };
+#endif // BGFX_CONFIG_USE_OVR
+
struct RendererContextD3D11 : public RendererContextI
{
RendererContextD3D11()
@@ -635,8 +799,6 @@ namespace bgfx { namespace d3d11
, m_fsChanges(0)
, m_rtMsaa(false)
, m_timerQuerySupport(false)
- , m_ovrRtv(NULL)
- , m_ovrDsv(NULL)
{
m_fbh.idx = invalidHandle;
memset(&m_adapterDesc, 0, sizeof(m_adapterDesc) );
@@ -2001,10 +2163,6 @@ BX_PRAGMA_DIAGNOSTIC_POP();
uint32_t width = getBufferWidth();
uint32_t height = getBufferHeight();
- if (m_ovr.isEnabled() )
- {
- m_ovr.getSize(width, height);
- }
FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
setFrameBuffer(fbh, false);
@@ -2192,7 +2350,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
if (SUCCEEDED(hr) )
{
- if (!m_ovr.swap(_hmd) )
+ if (!m_ovr.swap(_hmd, false) )
{
hr = m_swapChain->Present(syncInterval, 0);
}
@@ -3083,77 +3241,22 @@ BX_PRAGMA_DIAGNOSTIC_POP();
void ovrPostReset()
{
#if BGFX_CONFIG_USE_OVR
- if (m_flags & (BGFX_RESET_HMD|BGFX_RESET_HMD_DEBUG) )
+ if (m_resolution.m_flags & (BGFX_RESET_HMD|BGFX_RESET_HMD_DEBUG) )
{
- ovrD3D11Config config;
- config.D3D11.Header.API = ovrRenderAPI_D3D11;
-# if OVR_VERSION > OVR_VERSION_043
- config.D3D11.Header.BackBufferSize.w = m_scd.BufferDesc.Width;
- config.D3D11.Header.BackBufferSize.h = m_scd.BufferDesc.Height;
- config.D3D11.pBackBufferUAV = NULL;
-# else
- config.D3D11.Header.RTSize.w = m_scd.BufferDesc.Width;
- config.D3D11.Header.RTSize.h = m_scd.BufferDesc.Height;
-# endif // OVR_VERSION > OVR_VERSION_042
- config.D3D11.Header.Multisample = 0;
- config.D3D11.pDevice = m_device;
- config.D3D11.pDeviceContext = m_deviceCtx;
- config.D3D11.pBackBufferRT = m_backBufferColor;
- config.D3D11.pSwapChain = m_swapChain;
- if (m_ovr.postReset(g_platformData.nwh, &config.Config, !!(m_flags & BGFX_RESET_HMD_DEBUG) ) )
+ if (m_ovr.postReset())
{
- uint32_t size = sizeof(uint32_t) + sizeof(TextureCreate);
- const Memory* mem = alloc(size);
-
- bx::StaticMemoryBlockWriter writer(mem->data, mem->size);
- uint32_t magic = BGFX_CHUNK_MAGIC_TEX;
- bx::write(&writer, magic);
-
- TextureCreate tc;
- tc.m_flags = BGFX_TEXTURE_RT|( ((m_flags & BGFX_RESET_MSAA_MASK) >> BGFX_RESET_MSAA_SHIFT) << BGFX_TEXTURE_RT_MSAA_SHIFT);
- tc.m_width = m_ovr.m_rtSize.w;
- tc.m_height = m_ovr.m_rtSize.h;
- tc.m_sides = 0;
- tc.m_depth = 0;
- tc.m_numMips = 1;
- tc.m_format = uint8_t(bgfx::TextureFormat::BGRA8);
- tc.m_cubeMap = false;
- tc.m_mem = NULL;
- bx::write(&writer, tc);
- m_ovrRT.create(mem, tc.m_flags, 0);
-
- release(mem);
-
- DX_CHECK(m_device->CreateRenderTargetView(m_ovrRT.m_ptr, NULL, &m_ovrRtv) );
-
- D3D11_TEXTURE2D_DESC dsd;
- dsd.Width = m_ovr.m_rtSize.w;
- dsd.Height = m_ovr.m_rtSize.h;
- dsd.MipLevels = 1;
- dsd.ArraySize = 1;
- dsd.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
- dsd.SampleDesc = m_scd.SampleDesc;
- dsd.Usage = D3D11_USAGE_DEFAULT;
- dsd.BindFlags = D3D11_BIND_DEPTH_STENCIL;
- dsd.CPUAccessFlags = 0;
- dsd.MiscFlags = 0;
-
- ID3D11Texture2D* depthStencil;
- DX_CHECK(m_device->CreateTexture2D(&dsd, NULL, &depthStencil) );
- DX_CHECK(m_device->CreateDepthStencilView(depthStencil, NULL, &m_ovrDsv) );
- DX_RELEASE(depthStencil, 0);
-
- ovrD3D11Texture texture;
- texture.D3D11.Header.API = ovrRenderAPI_D3D11;
- texture.D3D11.Header.TextureSize = m_ovr.m_rtSize;
- texture.D3D11.pTexture = m_ovrRT.m_texture2d;
- texture.D3D11.pSRView = m_ovrRT.m_srv;
- m_ovr.postReset(texture.Texture);
-
- bx::xchg(m_ovrRtv, m_backBufferColor);
-
- BX_CHECK(NULL == m_backBufferDepthStencil, "");
- bx::xchg(m_ovrDsv, m_backBufferDepthStencil);
+ for (int eyeIdx = 0; eyeIdx < ovrEye_Count; eyeIdx++)
+ {
+ // eye buffers need to be initialized only once during application lifetime
+ if (!m_ovr.m_eyeBuffers[eyeIdx])
+ {
+ m_ovr.m_eyeBuffers[eyeIdx] = BX_NEW(g_allocator, OVRBufferDX11(m_ovr.m_hmd, eyeIdx, m_device, m_deviceCtx));
+ }
+ }
+
+ // recreate mirror texture
+ m_ovr.m_mirror = BX_NEW(g_allocator, OVRMirrorDX11(m_device, m_deviceCtx, m_swapChain));
+ m_ovr.m_mirror->init(m_ovr.m_hmd, m_resolution.m_width, m_resolution.m_height);
}
}
#endif // BGFX_CONFIG_USE_OVR
@@ -3163,16 +3266,6 @@ BX_PRAGMA_DIAGNOSTIC_POP();
{
#if BGFX_CONFIG_USE_OVR
m_ovr.preReset();
- if (NULL != m_ovrRtv)
- {
- bx::xchg(m_ovrRtv, m_backBufferColor);
- bx::xchg(m_ovrDsv, m_backBufferDepthStencil);
- BX_CHECK(NULL == m_backBufferDepthStencil, "");
-
- DX_RELEASE(m_ovrRtv, 0);
- DX_RELEASE(m_ovrDsv, 0);
- m_ovrRT.destroy();
- }
#endif // BGFX_CONFIG_USE_OVR
}
@@ -3564,9 +3657,6 @@ BX_PRAGMA_DIAGNOSTIC_POP();
bool m_timerQuerySupport;
OVR m_ovr;
- TextureD3D11 m_ovrRT;
- ID3D11RenderTargetView* m_ovrRtv;
- ID3D11DepthStencilView* m_ovrDsv;
};
static RendererContextD3D11* s_renderD3D11;
@@ -4864,7 +4954,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
_render->m_hmdInitialized = m_ovr.isInitialized();
- const bool hmdEnabled = m_ovr.isEnabled() || m_ovr.isDebug();
+ const bool hmdEnabled = m_ovr.isEnabled();
ViewState viewState(_render, hmdEnabled);
bool wireframe = !!(_render->m_debug&BGFX_DEBUG_WIREFRAME);
@@ -4987,6 +5077,9 @@ BX_PRAGMA_DIAGNOSTIC_POP();
if (m_ovr.isEnabled() )
{
m_ovr.getViewport(eye, &viewState.m_rect);
+ // commit previous eye to HMD and start rendering new frame
+ m_ovr.commitEye(eye);
+ m_ovr.renderEyeStart(eye);
}
else
{
diff --git a/3rdparty/bgfx/src/renderer_d3d11.h b/3rdparty/bgfx/src/renderer_d3d11.h
index dbe16a984d0..c1b4917ff80 100644
--- a/3rdparty/bgfx/src/renderer_d3d11.h
+++ b/3rdparty/bgfx/src/renderer_d3d11.h
@@ -32,8 +32,8 @@ BX_PRAGMA_DIAGNOSTIC_POP()
#include "renderer.h"
#include "renderer_d3d.h"
#include "shader_dxbc.h"
-#include "ovr.h"
-#include "renderdoc.h"
+#include "hmd_ovr.h"
+#include "debug_renderdoc.h"
#ifndef D3DCOLOR_ARGB
# define D3DCOLOR_ARGB(_a, _r, _g, _b) ( (DWORD)( ( ( (_a)&0xff)<<24)|( ( (_r)&0xff)<<16)|( ( (_g)&0xff)<<8)|( (_b)&0xff) ) )
diff --git a/3rdparty/bgfx/src/renderer_gl.cpp b/3rdparty/bgfx/src/renderer_gl.cpp
index ca09b64eba1..84afafbd5df 100644
--- a/3rdparty/bgfx/src/renderer_gl.cpp
+++ b/3rdparty/bgfx/src/renderer_gl.cpp
@@ -1274,6 +1274,144 @@ namespace bgfx { namespace gl
BX_UNUSED(supported);
}
+#if BGFX_CONFIG_USE_OVR
+
+ // Oculus Rift eye buffer
+ struct OVRBufferGL : public OVRBufferI
+ {
+ OVRBufferGL(const ovrSession& session, int eyeIdx)
+ {
+ ovrHmdDesc hmdDesc = ovr_GetHmdDesc(session);
+ m_eyeTextureSize = ovr_GetFovTextureSize(session, (ovrEyeType)eyeIdx, hmdDesc.DefaultEyeFov[eyeIdx], 1.0f);
+
+ ovrTextureSwapChainDesc desc = {};
+ desc.Type = ovrTexture_2D;
+ desc.ArraySize = 1;
+ desc.Width = m_eyeTextureSize.w;
+ desc.Height = m_eyeTextureSize.h;
+ desc.MipLevels = 1;
+ desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
+ desc.SampleCount = 1;
+ desc.StaticImage = ovrFalse;
+
+ ovr_CreateTextureSwapChainGL(session, &desc, &m_swapTextureChain);
+
+ int textureCount = 0;
+ ovr_GetTextureSwapChainLength(session, m_swapTextureChain, &textureCount);
+
+ for (int j = 0; j < textureCount; ++j)
+ {
+ GLuint chainTexId;
+ ovr_GetTextureSwapChainBufferGL(session, m_swapTextureChain, j, &chainTexId);
+ GL_CHECK(glBindTexture(GL_TEXTURE_2D, chainTexId));
+
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
+ }
+
+ GL_CHECK(glGenFramebuffers(1, &m_eyeFbo));
+
+ // create depth buffer
+ GL_CHECK(glGenTextures(1, &m_depthBuffer));
+ GL_CHECK(glBindTexture(GL_TEXTURE_2D, m_depthBuffer));
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
+
+ GL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, m_eyeTextureSize.w, m_eyeTextureSize.h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL));
+ }
+
+ void onRender(const ovrSession& session)
+ {
+ // set the current eye texture in swap chain
+ int curIndex;
+ ovr_GetTextureSwapChainCurrentIndex(session, m_swapTextureChain, &curIndex);
+ ovr_GetTextureSwapChainBufferGL(session, m_swapTextureChain, curIndex, &m_eyeTexId);
+
+ GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_eyeFbo));
+ GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_eyeTexId, 0));
+ GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthBuffer, 0));
+
+ GL_CHECK(glViewport(0, 0, m_eyeTextureSize.w, m_eyeTextureSize.h));
+ GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
+ }
+
+ void destroy(const ovrSession& session)
+ {
+ GL_CHECK(glDeleteFramebuffers(1, &m_eyeFbo));
+ GL_CHECK(glDeleteTextures(1, &m_depthBuffer));
+
+ ovr_DestroyTextureSwapChain(session, m_swapTextureChain);
+ }
+
+ GLuint m_eyeFbo;
+ GLuint m_eyeTexId;
+ GLuint m_depthBuffer;
+ };
+
+ // Oculus Rift mirror
+ struct OVRMirrorGL : public OVRMirrorI
+ {
+ void init(const ovrSession& session, int windowWidth, int windowHeight)
+ {
+ memset(&m_mirrorDesc, 0, sizeof(m_mirrorDesc));
+ m_mirrorDesc.Width = windowWidth;
+ m_mirrorDesc.Height = windowHeight;
+ m_mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
+
+ ovr_CreateMirrorTextureGL(session, &m_mirrorDesc, &m_mirrorTexture);
+
+ // Fallback to doing nothing if mirror was not created. This is to prevent errors with fast window resizes
+ if (!m_mirrorTexture)
+ return;
+
+ // Configure the mirror read buffer
+ GLuint texId;
+ ovr_GetMirrorTextureBufferGL(session, m_mirrorTexture, &texId);
+ GL_CHECK(glGenFramebuffers(1, &m_mirrorFBO));
+ GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, m_mirrorFBO));
+ GL_CHECK(glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0));
+ GL_CHECK(glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0));
+ GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0));
+
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+ {
+ GL_CHECK(glDeleteFramebuffers(1, &m_mirrorFBO));
+ BX_CHECK(false, "Could not initialize VR buffers!");
+ }
+ }
+
+ void destroy(const ovrSession& session)
+ {
+ if (!m_mirrorTexture)
+ return;
+
+ GL_CHECK(glDeleteFramebuffers(1, &m_mirrorFBO));
+ ovr_DestroyMirrorTexture(session, m_mirrorTexture);
+ m_mirrorTexture = NULL;
+ }
+
+ void blit(const ovrSession& /*session*/)
+ {
+ if (!m_mirrorTexture)
+ return;
+
+ // Blit mirror texture to back buffer
+ GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, m_mirrorFBO));
+ GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0));
+ GLint w = m_mirrorDesc.Width;
+ GLint h = m_mirrorDesc.Height;
+ GL_CHECK(glBlitFramebuffer(0, h, w, 0, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST));
+ GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0));
+ }
+
+ GLuint m_mirrorFBO;
+ };
+#endif // BGFX_CONFIG_USE_OVR
+
struct RendererContextGL : public RendererContextI
{
RendererContextGL()
@@ -1304,7 +1442,6 @@ namespace bgfx { namespace gl
, m_hash( (BX_PLATFORM_WINDOWS<<1) | BX_ARCH_64BIT)
, m_backBufferFbo(0)
, m_msaaBackBufferFbo(0)
- , m_ovrFbo(0)
{
memset(m_msaaBackBufferRbos, 0, sizeof(m_msaaBackBufferRbos) );
}
@@ -1818,6 +1955,17 @@ namespace bgfx { namespace gl
);
}
+// if (s_extension[Extension::ARB_clip_control].m_supported)
+// {
+// GL_CHECK(glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE) );
+// g_caps.originBottomLeft = true;
+// }
+// else
+ {
+ g_caps.homogeneousDepth = true;
+ g_caps.originBottomLeft = true;
+ }
+
m_vaoSupport = !!(BGFX_CONFIG_RENDERER_OPENGLES >= 30)
|| s_extension[Extension::ARB_vertex_array_object].m_supported
|| s_extension[Extension::OES_vertex_array_object].m_supported
@@ -2096,10 +2244,9 @@ namespace bgfx { namespace gl
m_glctx.swap(m_frameBuffers[m_windows[ii].idx].m_swapChain);
}
- if (!m_ovr.swap(_hmd) )
- {
- m_glctx.swap();
- }
+ m_ovr.swap(_hmd, true);
+ // need to swap GL render context even if OVR is enabled to get the mirror texture in the output
+ m_glctx.swap();
}
}
@@ -2386,10 +2533,6 @@ namespace bgfx { namespace gl
uint32_t width = m_resolution.m_width;
uint32_t height = m_resolution.m_height;
- if (m_ovr.isEnabled() )
- {
- m_ovr.getSize(width, height);
- }
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_backBufferFbo) );
GL_CHECK(glViewport(0, 0, width, height) );
@@ -2846,63 +2989,22 @@ namespace bgfx { namespace gl
void ovrPostReset()
{
#if BGFX_CONFIG_USE_OVR
- if (m_resolution.m_flags & (BGFX_RESET_HMD|BGFX_RESET_HMD_DEBUG) )
- {
- ovrGLConfig config;
- config.OGL.Header.API = ovrRenderAPI_OpenGL;
-# if OVR_VERSION > OVR_VERSION_043
- config.OGL.Header.BackBufferSize.w = m_resolution.m_width;
- config.OGL.Header.BackBufferSize.h = m_resolution.m_height;
-# else
- config.OGL.Header.RTSize.w = m_resolution.m_width;
- config.OGL.Header.RTSize.h = m_resolution.m_height;
-# endif // OVR_VERSION > OVR_VERSION_043
- config.OGL.Header.Multisample = 0;
- config.OGL.Window = (HWND)g_platformData.nwh;
- config.OGL.DC = GetDC(config.OGL.Window);
- if (m_ovr.postReset(g_platformData.nwh, &config.Config, !!(m_resolution.m_flags & BGFX_RESET_HMD_DEBUG) ) )
+ if (m_resolution.m_flags & (BGFX_RESET_HMD | BGFX_RESET_HMD_DEBUG))
+ {
+ if (m_ovr.postReset())
{
- uint32_t size = sizeof(uint32_t) + sizeof(TextureCreate);
- const Memory* mem = alloc(size);
-
- bx::StaticMemoryBlockWriter writer(mem->data, mem->size);
- uint32_t magic = BGFX_CHUNK_MAGIC_TEX;
- bx::write(&writer, magic);
-
- TextureCreate tc;
- tc.m_flags = BGFX_TEXTURE_RT|( ((m_resolution.m_flags & BGFX_RESET_MSAA_MASK) >> BGFX_RESET_MSAA_SHIFT) << BGFX_TEXTURE_RT_MSAA_SHIFT);;
- tc.m_width = m_ovr.m_rtSize.w;
- tc.m_height = m_ovr.m_rtSize.h;
- tc.m_sides = 0;
- tc.m_depth = 0;
- tc.m_numMips = 1;
- tc.m_format = uint8_t(bgfx::TextureFormat::BGRA8);
- tc.m_cubeMap = false;
- tc.m_mem = NULL;
- bx::write(&writer, tc);
-
- m_ovrRT.create(mem, tc.m_flags, 0);
- release(mem);
-
- m_ovrFbo = m_msaaBackBufferFbo;
-
- GL_CHECK(glGenFramebuffers(1, &m_msaaBackBufferFbo) );
- GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_msaaBackBufferFbo) );
-
- GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER
- , GL_COLOR_ATTACHMENT0
- , GL_TEXTURE_2D
- , m_ovrRT.m_id
- , 0
- ) );
-
- GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_ovrFbo) );
+ for (int eyeIdx = 0; eyeIdx < ovrEye_Count; eyeIdx++)
+ {
+ // eye buffers need to be initialized only once during application lifetime
+ if (!m_ovr.m_eyeBuffers[eyeIdx])
+ {
+ m_ovr.m_eyeBuffers[eyeIdx] = BX_NEW(g_allocator, OVRBufferGL(m_ovr.m_hmd, eyeIdx));
+ }
+ }
- ovrGLTexture texture;
- texture.OGL.Header.API = ovrRenderAPI_OpenGL;
- texture.OGL.Header.TextureSize = m_ovr.m_rtSize;
- texture.OGL.TexId = m_ovrRT.m_id;
- m_ovr.postReset(texture.Texture);
+ // recreate mirror texture
+ m_ovr.m_mirror = BX_NEW(g_allocator, OVRMirrorGL);
+ m_ovr.m_mirror->init(m_ovr.m_hmd, m_resolution.m_width, m_resolution.m_height);
}
}
#endif // BGFX_CONFIG_USE_OVR
@@ -2912,14 +3014,6 @@ namespace bgfx { namespace gl
{
#if BGFX_CONFIG_USE_OVR
m_ovr.preReset();
- if (m_ovr.isEnabled() )
- {
- GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
- GL_CHECK(glDeleteFramebuffers(1, &m_msaaBackBufferFbo) );
- m_msaaBackBufferFbo = m_ovrFbo;
- m_ovrFbo = 0;
- m_ovrRT.destroy();
- }
#endif // BGFX_CONFIG_USE_OVR
}
@@ -3343,8 +3437,6 @@ namespace bgfx { namespace gl
const char* m_glslVersion;
OVR m_ovr;
- TextureGL m_ovrRT;
- GLint m_ovrFbo;
};
RendererContextGL* s_renderGL;
@@ -3636,7 +3728,7 @@ namespace bgfx { namespace gl
}
m_numPredefined = 0;
- m_numSamplers = 0;
+ m_numSamplers = 0;
BX_TRACE("Uniforms (%d):", activeUniforms);
for (int32_t ii = 0; ii < activeUniforms; ++ii)
@@ -5428,7 +5520,7 @@ namespace bgfx { namespace gl
_render->m_hmdInitialized = m_ovr.isInitialized();
- const bool hmdEnabled = m_ovr.isEnabled() || m_ovr.isDebug();
+ const bool hmdEnabled = m_ovr.isEnabled();
ViewState viewState(_render, hmdEnabled);
uint16_t programIdx = invalidHandle;
@@ -5478,12 +5570,13 @@ namespace bgfx { namespace gl
m_occlusionQuery.resolve(_render);
}
+ uint8_t eye = 0;
+
if (0 == (_render->m_debug&BGFX_DEBUG_IFH) )
{
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_msaaBackBufferFbo) );
bool viewRestart = false;
- uint8_t eye = 0;
uint8_t restartState = 0;
viewState.m_rect = _render->m_rect[0];
@@ -5565,6 +5658,9 @@ namespace bgfx { namespace gl
if (m_ovr.isEnabled() )
{
m_ovr.getViewport(eye, &viewState.m_rect);
+ // commit previous eye to HMD and start rendering new frame
+ m_ovr.commitEye(eye);
+ m_ovr.renderEyeStart(eye);
}
else
{
@@ -5584,7 +5680,7 @@ namespace bgfx { namespace gl
}
const Rect& scissorRect = _render->m_scissor[view];
- viewHasScissor = !scissorRect.isZero();
+ viewHasScissor = !scissorRect.isZero();
viewScissorRect = viewHasScissor ? scissorRect : viewState.m_rect;
GL_CHECK(glViewport(viewState.m_rect.m_x
@@ -5666,7 +5762,7 @@ namespace bgfx { namespace gl
const RenderCompute& compute = renderItem.compute;
ProgramGL& program = m_program[key.m_program];
- GL_CHECK(glUseProgram(program.m_id) );
+ GL_CHECK(glUseProgram(program.m_id) );
GLbitfield barrier = 0;
for (uint32_t ii = 0; ii < BGFX_MAX_COMPUTE_BINDINGS; ++ii)
diff --git a/3rdparty/bgfx/src/renderer_gl.h b/3rdparty/bgfx/src/renderer_gl.h
index 65aebcbaa39..3bed1f17c80 100644
--- a/3rdparty/bgfx/src/renderer_gl.h
+++ b/3rdparty/bgfx/src/renderer_gl.h
@@ -107,8 +107,8 @@ typedef uint64_t GLuint64;
#endif // BGFX_CONFIG_RENDERER_OPENGL
#include "renderer.h"
-#include "ovr.h"
-#include "renderdoc.h"
+#include "hmd_ovr.h"
+#include "debug_renderdoc.h"
#ifndef GL_LUMINANCE
# define GL_LUMINANCE 0x1909
@@ -791,6 +791,22 @@ typedef uint64_t GLuint64;
# define GL_CONSERVATIVE_RASTERIZATION_NV 0x9346
#endif // GL_CONSERVATIVE_RASTERIZATION_NV
+#ifndef GL_NEGATIVE_ONE_TO_ONE
+# define GL_NEGATIVE_ONE_TO_ONE 0x935E
+#endif // GL_NEGATIVE_ONE_TO_ONE
+
+#ifndef GL_ZERO_TO_ONE
+# define GL_ZERO_TO_ONE 0x935F
+#endif // GL_ZERO_TO_ONE
+
+#ifndef GL_LOWER_LEFT
+# define GL_LOWER_LEFT 0x8CA1
+#endif // GL_LOWER_LEFT
+
+#ifndef GL_UPPER_LEFT
+# define GL_UPPER_LEFT 0x8CA2
+#endif // GL_UPPER_LEFT
+
// _KHR or _ARB...
#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243