Updated imgui to v1.91.8-docking.
This commit is contained in:
+67
-40
@@ -3,20 +3,28 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Clipboard support (from Allegro 5.1.12)
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// Issues:
|
||||
// [ ] Renderer: The renderer is suboptimal as we need to convert vertices manually.
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Clipboard support (from Allegro 5.1.12).
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// Missing features or Issues:
|
||||
// [ ] Renderer: The renderer is suboptimal as we need to unindex our buffers and convert vertices manually.
|
||||
// [ ] Platform: Missing gamepad support.
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-01-06: Avoid calling al_set_mouse_cursor() repeatedly since it appears to leak on on X11 (#8256).
|
||||
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
||||
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
|
||||
// - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn
|
||||
// 2022-11-30: Renderer: Restoring using al_draw_indexed_prim() when Allegro version is >= 5.2.5.
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
|
||||
@@ -24,7 +32,7 @@
|
||||
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
|
||||
// 2022-01-17: Inputs: always calling io.AddKeyModsEvent() next and before key event (not in NewFrame) to fix input queue with very low framerates.
|
||||
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
|
||||
// 2021-12-08: Renderer: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
|
||||
// 2021-12-08: Renderer: Fixed mishandling of the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
|
||||
// 2021-08-17: Calling io.AddFocusEvent() on ALLEGRO_EVENT_DISPLAY_SWITCH_OUT/ALLEGRO_EVENT_DISPLAY_SWITCH_IN events.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-05-19: Renderer: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
@@ -47,10 +55,11 @@
|
||||
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
|
||||
// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_allegro5.h"
|
||||
#include <stdint.h> // uint64_t
|
||||
#include <cstring> // memcpy
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_allegro5.h"
|
||||
|
||||
// Allegro
|
||||
#include <allegro5/allegro.h>
|
||||
@@ -58,8 +67,8 @@
|
||||
#ifdef _WIN32
|
||||
#include <allegro5/allegro_windows.h>
|
||||
#endif
|
||||
#define ALLEGRO_HAS_CLIPBOARD (ALLEGRO_VERSION_INT >= ((5 << 24) | (1 << 16) | (12 << 8))) // Clipboard only supported from Allegro 5.1.12
|
||||
#define ALLEGRO_HAS_DRAW_INDEXED_PRIM (ALLEGRO_VERSION_INT >= ((5 << 24) | (2 << 16) | ( 5 << 8))) // DX9 implementation of al_draw_indexed_prim() got fixed in Allegro 5.2.5
|
||||
#define ALLEGRO_HAS_CLIPBOARD ((ALLEGRO_VERSION_INT & ~ALLEGRO_UNSTABLE_BIT) >= ((5 << 24) | (1 << 16) | (12 << 8))) // Clipboard only supported from Allegro 5.1.12
|
||||
#define ALLEGRO_HAS_DRAW_INDEXED_PRIM ((ALLEGRO_VERSION_INT & ~ALLEGRO_UNSTABLE_BIT) >= ((5 << 24) | (2 << 16) | ( 5 << 8))) // DX9 implementation of al_draw_indexed_prim() got fixed in Allegro 5.2.5
|
||||
|
||||
// Visual Studio warnings
|
||||
#ifdef _MSC_VER
|
||||
@@ -88,6 +97,7 @@ struct ImGui_ImplAllegro5_Data
|
||||
ALLEGRO_MOUSE_CURSOR* MouseCursorInvisible;
|
||||
ALLEGRO_VERTEX_DECL* VertexDecl;
|
||||
char* ClipboardTextData;
|
||||
ImGuiMouseCursor LastCursor;
|
||||
|
||||
ImVector<ImDrawVertAllegro> BufVertices;
|
||||
ImVector<int> BufIndices;
|
||||
@@ -142,14 +152,14 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
|
||||
ImVector<ImDrawVertAllegro>& vertices = bd->BufVertices;
|
||||
#if ALLEGRO_HAS_DRAW_INDEXED_PRIM
|
||||
vertices.resize(cmd_list->VtxBuffer.Size);
|
||||
for (int i = 0; i < cmd_list->VtxBuffer.Size; i++)
|
||||
vertices.resize(draw_list->VtxBuffer.Size);
|
||||
for (int i = 0; i < draw_list->VtxBuffer.Size; i++)
|
||||
{
|
||||
const ImDrawVert* src_v = &cmd_list->VtxBuffer[i];
|
||||
const ImDrawVert* src_v = &draw_list->VtxBuffer[i];
|
||||
ImDrawVertAllegro* dst_v = &vertices[i];
|
||||
DRAW_VERT_IMGUI_TO_ALLEGRO(dst_v, src_v);
|
||||
}
|
||||
@@ -159,21 +169,21 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
||||
// FIXME-OPT: Allegro doesn't support 16-bit indices.
|
||||
// You can '#define ImDrawIdx int' in imconfig.h to request Dear ImGui to output 32-bit indices.
|
||||
// Otherwise, we convert them from 16-bit to 32-bit at runtime here, which works perfectly but is a little wasteful.
|
||||
bd->BufIndices.resize(cmd_list->IdxBuffer.Size);
|
||||
for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
|
||||
bd->BufIndices[i] = (int)cmd_list->IdxBuffer.Data[i];
|
||||
bd->BufIndices.resize(draw_list->IdxBuffer.Size);
|
||||
for (int i = 0; i < draw_list->IdxBuffer.Size; ++i)
|
||||
bd->BufIndices[i] = (int)draw_list->IdxBuffer.Data[i];
|
||||
indices = bd->BufIndices.Data;
|
||||
}
|
||||
else if (sizeof(ImDrawIdx) == 4)
|
||||
{
|
||||
indices = (const int*)cmd_list->IdxBuffer.Data;
|
||||
indices = (const int*)draw_list->IdxBuffer.Data;
|
||||
}
|
||||
#else
|
||||
// Allegro's implementation of al_draw_indexed_prim() for DX9 was broken until 5.2.5. Unindex buffers ourselves while converting vertex format.
|
||||
vertices.resize(cmd_list->IdxBuffer.Size);
|
||||
for (int i = 0; i < cmd_list->IdxBuffer.Size; i++)
|
||||
vertices.resize(draw_list->IdxBuffer.Size);
|
||||
for (int i = 0; i < draw_list->IdxBuffer.Size; i++)
|
||||
{
|
||||
const ImDrawVert* src_v = &cmd_list->VtxBuffer[cmd_list->IdxBuffer[i]];
|
||||
const ImDrawVert* src_v = &draw_list->VtxBuffer[draw_list->IdxBuffer[i]];
|
||||
ImDrawVertAllegro* dst_v = &vertices[i];
|
||||
DRAW_VERT_IMGUI_TO_ALLEGRO(dst_v, src_v);
|
||||
}
|
||||
@@ -181,9 +191,9 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
||||
|
||||
// Render command lists
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
@@ -191,7 +201,7 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplAllegro5_SetupRenderState(draw_data);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -287,7 +297,7 @@ void ImGui_ImplAllegro5_InvalidateDeviceObjects()
|
||||
}
|
||||
|
||||
#if ALLEGRO_HAS_CLIPBOARD
|
||||
static const char* ImGui_ImplAllegro5_GetClipboardText(void*)
|
||||
static const char* ImGui_ImplAllegro5_GetClipboardText(ImGuiContext*)
|
||||
{
|
||||
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
||||
if (bd->ClipboardTextData)
|
||||
@@ -296,14 +306,16 @@ static const char* ImGui_ImplAllegro5_GetClipboardText(void*)
|
||||
return bd->ClipboardTextData;
|
||||
}
|
||||
|
||||
static void ImGui_ImplAllegro5_SetClipboardText(void*, const char* text)
|
||||
static void ImGui_ImplAllegro5_SetClipboardText(ImGuiContext*, const char* text)
|
||||
{
|
||||
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
||||
al_set_clipboard_text(bd->Display, text);
|
||||
}
|
||||
#endif
|
||||
|
||||
static ImGuiKey ImGui_ImplAllegro5_KeyCodeToImGuiKey(int key_code)
|
||||
// Not static to allow third-party code to use that if they want to (but undocumented)
|
||||
ImGuiKey ImGui_ImplAllegro5_KeyCodeToImGuiKey(int key_code);
|
||||
ImGuiKey ImGui_ImplAllegro5_KeyCodeToImGuiKey(int key_code)
|
||||
{
|
||||
switch (key_code)
|
||||
{
|
||||
@@ -419,6 +431,7 @@ static ImGuiKey ImGui_ImplAllegro5_KeyCodeToImGuiKey(int key_code)
|
||||
bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
@@ -428,23 +441,24 @@ bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||
|
||||
bd->Display = display;
|
||||
bd->LastCursor = ALLEGRO_SYSTEM_MOUSE_CURSOR_NONE;
|
||||
|
||||
// Create custom vertex declaration.
|
||||
// Unfortunately Allegro doesn't support 32-bit packed colors so we have to convert them to 4 floats.
|
||||
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
|
||||
ALLEGRO_VERTEX_ELEMENT elems[] =
|
||||
{
|
||||
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, IM_OFFSETOF(ImDrawVertAllegro, pos) },
|
||||
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, IM_OFFSETOF(ImDrawVertAllegro, uv) },
|
||||
{ ALLEGRO_PRIM_COLOR_ATTR, 0, IM_OFFSETOF(ImDrawVertAllegro, col) },
|
||||
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, offsetof(ImDrawVertAllegro, pos) },
|
||||
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, offsetof(ImDrawVertAllegro, uv) },
|
||||
{ ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(ImDrawVertAllegro, col) },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
bd->VertexDecl = al_create_vertex_decl(elems, sizeof(ImDrawVertAllegro));
|
||||
|
||||
#if ALLEGRO_HAS_CLIPBOARD
|
||||
io.SetClipboardTextFn = ImGui_ImplAllegro5_SetClipboardText;
|
||||
io.GetClipboardTextFn = ImGui_ImplAllegro5_GetClipboardText;
|
||||
io.ClipboardUserData = nullptr;
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Platform_SetClipboardTextFn = ImGui_ImplAllegro5_SetClipboardText;
|
||||
platform_io.Platform_GetClipboardTextFn = ImGui_ImplAllegro5_GetClipboardText;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
@@ -462,8 +476,9 @@ void ImGui_ImplAllegro5_Shutdown()
|
||||
if (bd->ClipboardTextData)
|
||||
al_free(bd->ClipboardTextData);
|
||||
|
||||
io.BackendPlatformUserData = nullptr;
|
||||
io.BackendPlatformName = io.BackendRendererName = nullptr;
|
||||
io.BackendPlatformUserData = nullptr;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_HasMouseCursors;
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -485,8 +500,9 @@ static void ImGui_ImplAllegro5_UpdateKeyModifiers()
|
||||
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||
bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* ev)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplAllegro5_Init()?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
switch (ev->type)
|
||||
{
|
||||
@@ -556,9 +572,16 @@ static void ImGui_ImplAllegro5_UpdateMouseCursor()
|
||||
|
||||
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
||||
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
||||
if (io.MouseDrawCursor || imgui_cursor == ImGuiMouseCursor_None)
|
||||
|
||||
// Hide OS mouse cursor if imgui is drawing it
|
||||
if (io.MouseDrawCursor)
|
||||
imgui_cursor = ImGuiMouseCursor_None;
|
||||
|
||||
if (bd->LastCursor == imgui_cursor)
|
||||
return;
|
||||
bd->LastCursor = imgui_cursor;
|
||||
if (imgui_cursor == ImGuiMouseCursor_None)
|
||||
{
|
||||
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
|
||||
al_set_mouse_cursor(bd->Display, bd->MouseCursorInvisible);
|
||||
}
|
||||
else
|
||||
@@ -581,7 +604,7 @@ static void ImGui_ImplAllegro5_UpdateMouseCursor()
|
||||
void ImGui_ImplAllegro5_NewFrame()
|
||||
{
|
||||
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplAllegro5_Init()?");
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplAllegro5_Init()?");
|
||||
|
||||
if (!bd->Texture)
|
||||
ImGui_ImplAllegro5_CreateDeviceObjects();
|
||||
@@ -602,3 +625,7 @@ void ImGui_ImplAllegro5_NewFrame()
|
||||
// Setup mouse cursor shape
|
||||
ImGui_ImplAllegro5_UpdateMouseCursor();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+14
-6
@@ -3,24 +3,30 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ALLEGRO_BITMAP*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Clipboard support (from Allegro 5.1.12)
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// Issues:
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy ALLEGRO_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Clipboard support (from Allegro 5.1.12).
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// Missing features or Issues:
|
||||
// [ ] Renderer: The renderer is suboptimal as we need to unindex our buffers and convert vertices manually.
|
||||
// [ ] Platform: Missing gamepad support.
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
struct ALLEGRO_DISPLAY;
|
||||
union ALLEGRO_EVENT;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display);
|
||||
IMGUI_IMPL_API void ImGui_ImplAllegro5_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplAllegro5_NewFrame();
|
||||
@@ -30,3 +36,5 @@ IMGUI_IMPL_API bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* event);
|
||||
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||
IMGUI_IMPL_API bool ImGui_ImplAllegro5_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplAllegro5_InvalidateDeviceObjects();
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+309
@@ -0,0 +1,309 @@
|
||||
// dear imgui: Platform Binding for Android native app
|
||||
// This needs to be used along with the OpenGL 3 Renderer (imgui_impl_opengl3)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy AKEYCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
|
||||
// Missing features or Issues:
|
||||
// [ ] Platform: Clipboard support.
|
||||
// [ ] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [ ] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: Check if this is even possible with Android.
|
||||
// [ ] Platform: Multi-viewport support (multiple windows). Not meaningful on Android.
|
||||
// Important:
|
||||
// - Consider using SDL or GLFW backend on Android, which will be more full-featured than this.
|
||||
// - FIXME: On-screen keyboard currently needs to be enabled by the application (see examples/ and issue #3446)
|
||||
// - FIXME: Unicode character inputs needs to be passed by Dear ImGui by the application (see examples/ and issue #3446)
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
|
||||
// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago) with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
|
||||
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
|
||||
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
|
||||
// 2021-03-04: Initial version.
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_android.h"
|
||||
#include <time.h>
|
||||
#include <android/native_window.h>
|
||||
#include <android/input.h>
|
||||
#include <android/keycodes.h>
|
||||
#include <android/log.h>
|
||||
|
||||
// Android data
|
||||
static double g_Time = 0.0;
|
||||
static ANativeWindow* g_Window;
|
||||
static char g_LogTag[] = "ImGuiExample";
|
||||
|
||||
static ImGuiKey ImGui_ImplAndroid_KeyCodeToImGuiKey(int32_t key_code)
|
||||
{
|
||||
switch (key_code)
|
||||
{
|
||||
case AKEYCODE_TAB: return ImGuiKey_Tab;
|
||||
case AKEYCODE_DPAD_LEFT: return ImGuiKey_LeftArrow;
|
||||
case AKEYCODE_DPAD_RIGHT: return ImGuiKey_RightArrow;
|
||||
case AKEYCODE_DPAD_UP: return ImGuiKey_UpArrow;
|
||||
case AKEYCODE_DPAD_DOWN: return ImGuiKey_DownArrow;
|
||||
case AKEYCODE_PAGE_UP: return ImGuiKey_PageUp;
|
||||
case AKEYCODE_PAGE_DOWN: return ImGuiKey_PageDown;
|
||||
case AKEYCODE_MOVE_HOME: return ImGuiKey_Home;
|
||||
case AKEYCODE_MOVE_END: return ImGuiKey_End;
|
||||
case AKEYCODE_INSERT: return ImGuiKey_Insert;
|
||||
case AKEYCODE_FORWARD_DEL: return ImGuiKey_Delete;
|
||||
case AKEYCODE_DEL: return ImGuiKey_Backspace;
|
||||
case AKEYCODE_SPACE: return ImGuiKey_Space;
|
||||
case AKEYCODE_ENTER: return ImGuiKey_Enter;
|
||||
case AKEYCODE_ESCAPE: return ImGuiKey_Escape;
|
||||
case AKEYCODE_APOSTROPHE: return ImGuiKey_Apostrophe;
|
||||
case AKEYCODE_COMMA: return ImGuiKey_Comma;
|
||||
case AKEYCODE_MINUS: return ImGuiKey_Minus;
|
||||
case AKEYCODE_PERIOD: return ImGuiKey_Period;
|
||||
case AKEYCODE_SLASH: return ImGuiKey_Slash;
|
||||
case AKEYCODE_SEMICOLON: return ImGuiKey_Semicolon;
|
||||
case AKEYCODE_EQUALS: return ImGuiKey_Equal;
|
||||
case AKEYCODE_LEFT_BRACKET: return ImGuiKey_LeftBracket;
|
||||
case AKEYCODE_BACKSLASH: return ImGuiKey_Backslash;
|
||||
case AKEYCODE_RIGHT_BRACKET: return ImGuiKey_RightBracket;
|
||||
case AKEYCODE_GRAVE: return ImGuiKey_GraveAccent;
|
||||
case AKEYCODE_CAPS_LOCK: return ImGuiKey_CapsLock;
|
||||
case AKEYCODE_SCROLL_LOCK: return ImGuiKey_ScrollLock;
|
||||
case AKEYCODE_NUM_LOCK: return ImGuiKey_NumLock;
|
||||
case AKEYCODE_SYSRQ: return ImGuiKey_PrintScreen;
|
||||
case AKEYCODE_BREAK: return ImGuiKey_Pause;
|
||||
case AKEYCODE_NUMPAD_0: return ImGuiKey_Keypad0;
|
||||
case AKEYCODE_NUMPAD_1: return ImGuiKey_Keypad1;
|
||||
case AKEYCODE_NUMPAD_2: return ImGuiKey_Keypad2;
|
||||
case AKEYCODE_NUMPAD_3: return ImGuiKey_Keypad3;
|
||||
case AKEYCODE_NUMPAD_4: return ImGuiKey_Keypad4;
|
||||
case AKEYCODE_NUMPAD_5: return ImGuiKey_Keypad5;
|
||||
case AKEYCODE_NUMPAD_6: return ImGuiKey_Keypad6;
|
||||
case AKEYCODE_NUMPAD_7: return ImGuiKey_Keypad7;
|
||||
case AKEYCODE_NUMPAD_8: return ImGuiKey_Keypad8;
|
||||
case AKEYCODE_NUMPAD_9: return ImGuiKey_Keypad9;
|
||||
case AKEYCODE_NUMPAD_DOT: return ImGuiKey_KeypadDecimal;
|
||||
case AKEYCODE_NUMPAD_DIVIDE: return ImGuiKey_KeypadDivide;
|
||||
case AKEYCODE_NUMPAD_MULTIPLY: return ImGuiKey_KeypadMultiply;
|
||||
case AKEYCODE_NUMPAD_SUBTRACT: return ImGuiKey_KeypadSubtract;
|
||||
case AKEYCODE_NUMPAD_ADD: return ImGuiKey_KeypadAdd;
|
||||
case AKEYCODE_NUMPAD_ENTER: return ImGuiKey_KeypadEnter;
|
||||
case AKEYCODE_NUMPAD_EQUALS: return ImGuiKey_KeypadEqual;
|
||||
case AKEYCODE_CTRL_LEFT: return ImGuiKey_LeftCtrl;
|
||||
case AKEYCODE_SHIFT_LEFT: return ImGuiKey_LeftShift;
|
||||
case AKEYCODE_ALT_LEFT: return ImGuiKey_LeftAlt;
|
||||
case AKEYCODE_META_LEFT: return ImGuiKey_LeftSuper;
|
||||
case AKEYCODE_CTRL_RIGHT: return ImGuiKey_RightCtrl;
|
||||
case AKEYCODE_SHIFT_RIGHT: return ImGuiKey_RightShift;
|
||||
case AKEYCODE_ALT_RIGHT: return ImGuiKey_RightAlt;
|
||||
case AKEYCODE_META_RIGHT: return ImGuiKey_RightSuper;
|
||||
case AKEYCODE_MENU: return ImGuiKey_Menu;
|
||||
case AKEYCODE_0: return ImGuiKey_0;
|
||||
case AKEYCODE_1: return ImGuiKey_1;
|
||||
case AKEYCODE_2: return ImGuiKey_2;
|
||||
case AKEYCODE_3: return ImGuiKey_3;
|
||||
case AKEYCODE_4: return ImGuiKey_4;
|
||||
case AKEYCODE_5: return ImGuiKey_5;
|
||||
case AKEYCODE_6: return ImGuiKey_6;
|
||||
case AKEYCODE_7: return ImGuiKey_7;
|
||||
case AKEYCODE_8: return ImGuiKey_8;
|
||||
case AKEYCODE_9: return ImGuiKey_9;
|
||||
case AKEYCODE_A: return ImGuiKey_A;
|
||||
case AKEYCODE_B: return ImGuiKey_B;
|
||||
case AKEYCODE_C: return ImGuiKey_C;
|
||||
case AKEYCODE_D: return ImGuiKey_D;
|
||||
case AKEYCODE_E: return ImGuiKey_E;
|
||||
case AKEYCODE_F: return ImGuiKey_F;
|
||||
case AKEYCODE_G: return ImGuiKey_G;
|
||||
case AKEYCODE_H: return ImGuiKey_H;
|
||||
case AKEYCODE_I: return ImGuiKey_I;
|
||||
case AKEYCODE_J: return ImGuiKey_J;
|
||||
case AKEYCODE_K: return ImGuiKey_K;
|
||||
case AKEYCODE_L: return ImGuiKey_L;
|
||||
case AKEYCODE_M: return ImGuiKey_M;
|
||||
case AKEYCODE_N: return ImGuiKey_N;
|
||||
case AKEYCODE_O: return ImGuiKey_O;
|
||||
case AKEYCODE_P: return ImGuiKey_P;
|
||||
case AKEYCODE_Q: return ImGuiKey_Q;
|
||||
case AKEYCODE_R: return ImGuiKey_R;
|
||||
case AKEYCODE_S: return ImGuiKey_S;
|
||||
case AKEYCODE_T: return ImGuiKey_T;
|
||||
case AKEYCODE_U: return ImGuiKey_U;
|
||||
case AKEYCODE_V: return ImGuiKey_V;
|
||||
case AKEYCODE_W: return ImGuiKey_W;
|
||||
case AKEYCODE_X: return ImGuiKey_X;
|
||||
case AKEYCODE_Y: return ImGuiKey_Y;
|
||||
case AKEYCODE_Z: return ImGuiKey_Z;
|
||||
case AKEYCODE_F1: return ImGuiKey_F1;
|
||||
case AKEYCODE_F2: return ImGuiKey_F2;
|
||||
case AKEYCODE_F3: return ImGuiKey_F3;
|
||||
case AKEYCODE_F4: return ImGuiKey_F4;
|
||||
case AKEYCODE_F5: return ImGuiKey_F5;
|
||||
case AKEYCODE_F6: return ImGuiKey_F6;
|
||||
case AKEYCODE_F7: return ImGuiKey_F7;
|
||||
case AKEYCODE_F8: return ImGuiKey_F8;
|
||||
case AKEYCODE_F9: return ImGuiKey_F9;
|
||||
case AKEYCODE_F10: return ImGuiKey_F10;
|
||||
case AKEYCODE_F11: return ImGuiKey_F11;
|
||||
case AKEYCODE_F12: return ImGuiKey_F12;
|
||||
default: return ImGuiKey_None;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ImGui_ImplAndroid_HandleInputEvent(const AInputEvent* input_event)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
int32_t event_type = AInputEvent_getType(input_event);
|
||||
switch (event_type)
|
||||
{
|
||||
case AINPUT_EVENT_TYPE_KEY:
|
||||
{
|
||||
int32_t event_key_code = AKeyEvent_getKeyCode(input_event);
|
||||
int32_t event_scan_code = AKeyEvent_getScanCode(input_event);
|
||||
int32_t event_action = AKeyEvent_getAction(input_event);
|
||||
int32_t event_meta_state = AKeyEvent_getMetaState(input_event);
|
||||
|
||||
io.AddKeyEvent(ImGuiMod_Ctrl, (event_meta_state & AMETA_CTRL_ON) != 0);
|
||||
io.AddKeyEvent(ImGuiMod_Shift, (event_meta_state & AMETA_SHIFT_ON) != 0);
|
||||
io.AddKeyEvent(ImGuiMod_Alt, (event_meta_state & AMETA_ALT_ON) != 0);
|
||||
io.AddKeyEvent(ImGuiMod_Super, (event_meta_state & AMETA_META_ON) != 0);
|
||||
|
||||
switch (event_action)
|
||||
{
|
||||
// FIXME: AKEY_EVENT_ACTION_DOWN and AKEY_EVENT_ACTION_UP occur at once as soon as a touch pointer
|
||||
// goes up from a key. We use a simple key event queue/ and process one event per key per frame in
|
||||
// ImGui_ImplAndroid_NewFrame()...or consider using IO queue, if suitable: https://github.com/ocornut/imgui/issues/2787
|
||||
case AKEY_EVENT_ACTION_DOWN:
|
||||
case AKEY_EVENT_ACTION_UP:
|
||||
{
|
||||
ImGuiKey key = ImGui_ImplAndroid_KeyCodeToImGuiKey(event_key_code);
|
||||
if (key != ImGuiKey_None)
|
||||
{
|
||||
io.AddKeyEvent(key, event_action == AKEY_EVENT_ACTION_DOWN);
|
||||
io.SetKeyEventNativeData(key, event_key_code, event_scan_code);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AINPUT_EVENT_TYPE_MOTION:
|
||||
{
|
||||
int32_t event_action = AMotionEvent_getAction(input_event);
|
||||
int32_t event_pointer_index = (event_action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
|
||||
event_action &= AMOTION_EVENT_ACTION_MASK;
|
||||
|
||||
switch (AMotionEvent_getToolType(input_event, event_pointer_index))
|
||||
{
|
||||
case AMOTION_EVENT_TOOL_TYPE_MOUSE:
|
||||
io.AddMouseSourceEvent(ImGuiMouseSource_Mouse);
|
||||
break;
|
||||
case AMOTION_EVENT_TOOL_TYPE_STYLUS:
|
||||
case AMOTION_EVENT_TOOL_TYPE_ERASER:
|
||||
io.AddMouseSourceEvent(ImGuiMouseSource_Pen);
|
||||
break;
|
||||
case AMOTION_EVENT_TOOL_TYPE_FINGER:
|
||||
default:
|
||||
io.AddMouseSourceEvent(ImGuiMouseSource_TouchScreen);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (event_action)
|
||||
{
|
||||
case AMOTION_EVENT_ACTION_DOWN:
|
||||
case AMOTION_EVENT_ACTION_UP:
|
||||
{
|
||||
// Physical mouse buttons (and probably other physical devices) also invoke the actions AMOTION_EVENT_ACTION_DOWN/_UP,
|
||||
// but we have to process them separately to identify the actual button pressed. This is done below via
|
||||
// AMOTION_EVENT_ACTION_BUTTON_PRESS/_RELEASE. Here, we only process "FINGER" input (and "UNKNOWN", as a fallback).
|
||||
int tool_type = AMotionEvent_getToolType(input_event, event_pointer_index);
|
||||
if (tool_type == AMOTION_EVENT_TOOL_TYPE_FINGER || tool_type == AMOTION_EVENT_TOOL_TYPE_UNKNOWN)
|
||||
{
|
||||
io.AddMousePosEvent(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index));
|
||||
io.AddMouseButtonEvent(0, event_action == AMOTION_EVENT_ACTION_DOWN);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AMOTION_EVENT_ACTION_BUTTON_PRESS:
|
||||
case AMOTION_EVENT_ACTION_BUTTON_RELEASE:
|
||||
{
|
||||
int32_t button_state = AMotionEvent_getButtonState(input_event);
|
||||
io.AddMouseButtonEvent(0, (button_state & AMOTION_EVENT_BUTTON_PRIMARY) != 0);
|
||||
io.AddMouseButtonEvent(1, (button_state & AMOTION_EVENT_BUTTON_SECONDARY) != 0);
|
||||
io.AddMouseButtonEvent(2, (button_state & AMOTION_EVENT_BUTTON_TERTIARY) != 0);
|
||||
break;
|
||||
}
|
||||
case AMOTION_EVENT_ACTION_HOVER_MOVE: // Hovering: Tool moves while NOT pressed (such as a physical mouse)
|
||||
case AMOTION_EVENT_ACTION_MOVE: // Touch pointer moves while DOWN
|
||||
io.AddMousePosEvent(AMotionEvent_getX(input_event, event_pointer_index), AMotionEvent_getY(input_event, event_pointer_index));
|
||||
break;
|
||||
case AMOTION_EVENT_ACTION_SCROLL:
|
||||
io.AddMouseWheelEvent(AMotionEvent_getAxisValue(input_event, AMOTION_EVENT_AXIS_HSCROLL, event_pointer_index), AMotionEvent_getAxisValue(input_event, AMOTION_EVENT_AXIS_VSCROLL, event_pointer_index));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ImGui_ImplAndroid_Init(ANativeWindow* window)
|
||||
{
|
||||
IMGUI_CHECKVERSION();
|
||||
|
||||
g_Window = window;
|
||||
g_Time = 0.0;
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.BackendPlatformName = "imgui_impl_android";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplAndroid_Shutdown()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.BackendPlatformName = nullptr;
|
||||
}
|
||||
|
||||
void ImGui_ImplAndroid_NewFrame()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Setup display size (every frame to accommodate for window resizing)
|
||||
int32_t window_width = ANativeWindow_getWidth(g_Window);
|
||||
int32_t window_height = ANativeWindow_getHeight(g_Window);
|
||||
int display_width = window_width;
|
||||
int display_height = window_height;
|
||||
|
||||
io.DisplaySize = ImVec2((float)window_width, (float)window_height);
|
||||
if (window_width > 0 && window_height > 0)
|
||||
io.DisplayFramebufferScale = ImVec2((float)display_width / window_width, (float)display_height / window_height);
|
||||
|
||||
// Setup time step
|
||||
struct timespec current_timespec;
|
||||
clock_gettime(CLOCK_MONOTONIC, ¤t_timespec);
|
||||
double current_time = (double)(current_timespec.tv_sec) + (current_timespec.tv_nsec / 1000000000.0);
|
||||
io.DeltaTime = g_Time > 0.0 ? (float)(current_time - g_Time) : (float)(1.0f / 60.0f);
|
||||
g_Time = current_time;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
// dear imgui: Platform Binding for Android native app
|
||||
// This needs to be used along with the OpenGL 3 Renderer (imgui_impl_opengl3)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy AKEYCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
|
||||
// Missing features or Issues:
|
||||
// [ ] Platform: Clipboard support.
|
||||
// [ ] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [ ] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: Check if this is even possible with Android.
|
||||
// [ ] Platform: Multi-viewport support (multiple windows). Not meaningful on Android.
|
||||
// Important:
|
||||
// - Consider using SDL or GLFW backend on Android, which will be more full-featured than this.
|
||||
// - FIXME: On-screen keyboard currently needs to be enabled by the application (see examples/ and issue #3446)
|
||||
// - FIXME: Unicode character inputs needs to be passed by Dear ImGui by the application (see examples/ and issue #3446)
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
struct ANativeWindow;
|
||||
struct AInputEvent;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplAndroid_Init(ANativeWindow* window);
|
||||
IMGUI_IMPL_API int32_t ImGui_ImplAndroid_HandleInputEvent(const AInputEvent* input_event);
|
||||
IMGUI_IMPL_API void ImGui_ImplAndroid_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplAndroid_NewFrame();
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
+184
-154
@@ -3,17 +3,22 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-01-06: DirectX10: Expose selected render state in ImGui_ImplDX10_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||
// 2024-10-07: DirectX10: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-05-19: DirectX10: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
@@ -32,6 +37,7 @@
|
||||
// 2016-05-07: DirectX10: Disabling depth-write.
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_dx10.h"
|
||||
|
||||
// DirectX
|
||||
@@ -43,7 +49,7 @@
|
||||
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
||||
#endif
|
||||
|
||||
// DirectX data
|
||||
// DirectX10 data
|
||||
struct ImGui_ImplDX10_Data
|
||||
{
|
||||
ID3D10Device* pd3dDevice;
|
||||
@@ -78,11 +84,11 @@ static ImGui_ImplDX10_Data* ImGui_ImplDX10_GetBackendData()
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplDX10_InitPlatformInterface();
|
||||
static void ImGui_ImplDX10_ShutdownPlatformInterface();
|
||||
static void ImGui_ImplDX10_InitMultiViewportSupport();
|
||||
static void ImGui_ImplDX10_ShutdownMultiViewportSupport();
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device* ctx)
|
||||
static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device* device)
|
||||
{
|
||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||
|
||||
@@ -94,90 +100,13 @@ static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device*
|
||||
vp.MinDepth = 0.0f;
|
||||
vp.MaxDepth = 1.0f;
|
||||
vp.TopLeftX = vp.TopLeftY = 0;
|
||||
ctx->RSSetViewports(1, &vp);
|
||||
|
||||
// Bind shader and vertex buffers
|
||||
unsigned int stride = sizeof(ImDrawVert);
|
||||
unsigned int offset = 0;
|
||||
ctx->IASetInputLayout(bd->pInputLayout);
|
||||
ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
|
||||
ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
||||
ctx->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
ctx->VSSetShader(bd->pVertexShader);
|
||||
ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
||||
ctx->PSSetShader(bd->pPixelShader);
|
||||
ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
|
||||
ctx->GSSetShader(nullptr);
|
||||
|
||||
// Setup render state
|
||||
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||
ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
|
||||
ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0);
|
||||
ctx->RSSetState(bd->pRasterizerState);
|
||||
}
|
||||
|
||||
// Render function
|
||||
void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
// Avoid rendering when minimized
|
||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||
return;
|
||||
|
||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||
ID3D10Device* ctx = bd->pd3dDevice;
|
||||
|
||||
// Create and grow vertex/index buffers if needed
|
||||
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
||||
{
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||
D3D10_BUFFER_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D10_BUFFER_DESC));
|
||||
desc.Usage = D3D10_USAGE_DYNAMIC;
|
||||
desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert);
|
||||
desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
|
||||
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
|
||||
desc.MiscFlags = 0;
|
||||
if (ctx->CreateBuffer(&desc, nullptr, &bd->pVB) < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
||||
{
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||
D3D10_BUFFER_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D10_BUFFER_DESC));
|
||||
desc.Usage = D3D10_USAGE_DYNAMIC;
|
||||
desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
|
||||
desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
|
||||
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
|
||||
if (ctx->CreateBuffer(&desc, nullptr, &bd->pIB) < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy and convert all vertices into a single contiguous buffer
|
||||
ImDrawVert* vtx_dst = nullptr;
|
||||
ImDrawIdx* idx_dst = nullptr;
|
||||
bd->pVB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&vtx_dst);
|
||||
bd->pIB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&idx_dst);
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += cmd_list->VtxBuffer.Size;
|
||||
idx_dst += cmd_list->IdxBuffer.Size;
|
||||
}
|
||||
bd->pVB->Unmap();
|
||||
bd->pIB->Unmap();
|
||||
device->RSSetViewports(1, &vp);
|
||||
|
||||
// Setup orthographic projection matrix into our constant buffer
|
||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||
void* mapped_resource;
|
||||
if (bd->pVertexConstantBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mapped_resource) == S_OK)
|
||||
{
|
||||
void* mapped_resource;
|
||||
if (bd->pVertexConstantBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
|
||||
return;
|
||||
VERTEX_CONSTANT_BUFFER_DX10* constant_buffer = (VERTEX_CONSTANT_BUFFER_DX10*)mapped_resource;
|
||||
float L = draw_data->DisplayPos.x;
|
||||
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||
@@ -194,6 +123,82 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
||||
bd->pVertexConstantBuffer->Unmap();
|
||||
}
|
||||
|
||||
// Setup shader and vertex buffers
|
||||
unsigned int stride = sizeof(ImDrawVert);
|
||||
unsigned int offset = 0;
|
||||
device->IASetInputLayout(bd->pInputLayout);
|
||||
device->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
|
||||
device->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
||||
device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
device->VSSetShader(bd->pVertexShader);
|
||||
device->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
||||
device->PSSetShader(bd->pPixelShader);
|
||||
device->PSSetSamplers(0, 1, &bd->pFontSampler);
|
||||
device->GSSetShader(nullptr);
|
||||
|
||||
// Setup render state
|
||||
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||
device->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
|
||||
device->OMSetDepthStencilState(bd->pDepthStencilState, 0);
|
||||
device->RSSetState(bd->pRasterizerState);
|
||||
}
|
||||
|
||||
// Render function
|
||||
void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
// Avoid rendering when minimized
|
||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||
return;
|
||||
|
||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||
ID3D10Device* device = bd->pd3dDevice;
|
||||
|
||||
// Create and grow vertex/index buffers if needed
|
||||
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
||||
{
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||
D3D10_BUFFER_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D10_BUFFER_DESC));
|
||||
desc.Usage = D3D10_USAGE_DYNAMIC;
|
||||
desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert);
|
||||
desc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
|
||||
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
|
||||
desc.MiscFlags = 0;
|
||||
if (device->CreateBuffer(&desc, nullptr, &bd->pVB) < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
||||
{
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||
D3D10_BUFFER_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D10_BUFFER_DESC));
|
||||
desc.Usage = D3D10_USAGE_DYNAMIC;
|
||||
desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
|
||||
desc.BindFlags = D3D10_BIND_INDEX_BUFFER;
|
||||
desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
|
||||
if (device->CreateBuffer(&desc, nullptr, &bd->pIB) < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
// Copy and convert all vertices into a single contiguous buffer
|
||||
ImDrawVert* vtx_dst = nullptr;
|
||||
ImDrawIdx* idx_dst = nullptr;
|
||||
bd->pVB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&vtx_dst);
|
||||
bd->pIB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&idx_dst);
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
idx_dst += draw_list->IdxBuffer.Size;
|
||||
}
|
||||
bd->pVB->Unmap();
|
||||
bd->pIB->Unmap();
|
||||
|
||||
// Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
|
||||
struct BACKUP_DX10_STATE
|
||||
{
|
||||
@@ -219,24 +224,31 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
||||
};
|
||||
BACKUP_DX10_STATE old = {};
|
||||
old.ScissorRectsCount = old.ViewportsCount = D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
|
||||
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
|
||||
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
|
||||
ctx->RSGetState(&old.RS);
|
||||
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
|
||||
ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
|
||||
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
|
||||
ctx->PSGetSamplers(0, 1, &old.PSSampler);
|
||||
ctx->PSGetShader(&old.PS);
|
||||
ctx->VSGetShader(&old.VS);
|
||||
ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
|
||||
ctx->GSGetShader(&old.GS);
|
||||
ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology);
|
||||
ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
|
||||
ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
|
||||
ctx->IAGetInputLayout(&old.InputLayout);
|
||||
device->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
|
||||
device->RSGetViewports(&old.ViewportsCount, old.Viewports);
|
||||
device->RSGetState(&old.RS);
|
||||
device->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
|
||||
device->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
|
||||
device->PSGetShaderResources(0, 1, &old.PSShaderResource);
|
||||
device->PSGetSamplers(0, 1, &old.PSSampler);
|
||||
device->PSGetShader(&old.PS);
|
||||
device->VSGetShader(&old.VS);
|
||||
device->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
|
||||
device->GSGetShader(&old.GS);
|
||||
device->IAGetPrimitiveTopology(&old.PrimitiveTopology);
|
||||
device->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
|
||||
device->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
|
||||
device->IAGetInputLayout(&old.InputLayout);
|
||||
|
||||
// Setup desired DX state
|
||||
ImGui_ImplDX10_SetupRenderState(draw_data, ctx);
|
||||
ImGui_ImplDX10_SetupRenderState(draw_data, device);
|
||||
// Setup render state structure (for callbacks and custom texture bindings)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
ImGui_ImplDX10_RenderState render_state;
|
||||
render_state.Device = bd->pd3dDevice;
|
||||
render_state.SamplerDefault = bd->pFontSampler;
|
||||
render_state.VertexConstantBuffer = bd->pVertexConstantBuffer;
|
||||
platform_io.Renderer_RenderState = &render_state;
|
||||
|
||||
// Render command lists
|
||||
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||
@@ -245,18 +257,18 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback)
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplDX10_SetupRenderState(draw_data, ctx);
|
||||
ImGui_ImplDX10_SetupRenderState(draw_data, device);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -268,34 +280,35 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
||||
|
||||
// Apply scissor/clipping rectangle
|
||||
const D3D10_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||
ctx->RSSetScissorRects(1, &r);
|
||||
device->RSSetScissorRects(1, &r);
|
||||
|
||||
// Bind texture, Draw
|
||||
ID3D10ShaderResourceView* texture_srv = (ID3D10ShaderResourceView*)pcmd->GetTexID();
|
||||
ctx->PSSetShaderResources(0, 1, &texture_srv);
|
||||
ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
|
||||
device->PSSetShaderResources(0, 1, &texture_srv);
|
||||
device->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
|
||||
}
|
||||
}
|
||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
||||
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
||||
global_idx_offset += draw_list->IdxBuffer.Size;
|
||||
global_vtx_offset += draw_list->VtxBuffer.Size;
|
||||
}
|
||||
platform_io.Renderer_RenderState = nullptr;
|
||||
|
||||
// Restore modified DX state
|
||||
ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
|
||||
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
|
||||
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
|
||||
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
|
||||
ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
|
||||
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
|
||||
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
|
||||
ctx->PSSetShader(old.PS); if (old.PS) old.PS->Release();
|
||||
ctx->VSSetShader(old.VS); if (old.VS) old.VS->Release();
|
||||
ctx->GSSetShader(old.GS); if (old.GS) old.GS->Release();
|
||||
ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
|
||||
ctx->IASetPrimitiveTopology(old.PrimitiveTopology);
|
||||
ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
|
||||
ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
|
||||
ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
|
||||
device->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
|
||||
device->RSSetViewports(old.ViewportsCount, old.Viewports);
|
||||
device->RSSetState(old.RS); if (old.RS) old.RS->Release();
|
||||
device->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
|
||||
device->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
|
||||
device->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
|
||||
device->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
|
||||
device->PSSetShader(old.PS); if (old.PS) old.PS->Release();
|
||||
device->VSSetShader(old.VS); if (old.VS) old.VS->Release();
|
||||
device->GSSetShader(old.GS); if (old.GS) old.GS->Release();
|
||||
device->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
|
||||
device->IASetPrimitiveTopology(old.PrimitiveTopology);
|
||||
device->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
|
||||
device->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
|
||||
device->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX10_CreateFontsTexture()
|
||||
@@ -342,21 +355,16 @@ static void ImGui_ImplDX10_CreateFontsTexture()
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID((ImTextureID)bd->pFontTextureView);
|
||||
}
|
||||
|
||||
// Create texture sampler
|
||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||
static void ImGui_ImplDX10_DestroyFontsTexture()
|
||||
{
|
||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||
if (bd->pFontTextureView)
|
||||
{
|
||||
D3D10_SAMPLER_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
desc.AddressU = D3D10_TEXTURE_ADDRESS_WRAP;
|
||||
desc.AddressV = D3D10_TEXTURE_ADDRESS_WRAP;
|
||||
desc.AddressW = D3D10_TEXTURE_ADDRESS_WRAP;
|
||||
desc.MipLODBias = 0.f;
|
||||
desc.ComparisonFunc = D3D10_COMPARISON_ALWAYS;
|
||||
desc.MinLOD = 0.f;
|
||||
desc.MaxLOD = 0.f;
|
||||
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
|
||||
bd->pFontTextureView->Release();
|
||||
bd->pFontTextureView = nullptr;
|
||||
ImGui::GetIO().Fonts->SetTexID(0); // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -416,9 +424,9 @@ bool ImGui_ImplDX10_CreateDeviceObjects()
|
||||
// Create the input layout
|
||||
D3D10_INPUT_ELEMENT_DESC local_layout[] =
|
||||
{
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, pos), D3D10_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, uv), D3D10_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)IM_OFFSETOF(ImDrawVert, col), D3D10_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, pos), D3D10_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, uv), D3D10_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)offsetof(ImDrawVert, col), D3D10_INPUT_PER_VERTEX_DATA, 0 },
|
||||
};
|
||||
if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK)
|
||||
{
|
||||
@@ -509,6 +517,22 @@ bool ImGui_ImplDX10_CreateDeviceObjects()
|
||||
bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState);
|
||||
}
|
||||
|
||||
// Create texture sampler
|
||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||
{
|
||||
D3D10_SAMPLER_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.Filter = D3D10_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
desc.AddressU = D3D10_TEXTURE_ADDRESS_CLAMP;
|
||||
desc.AddressV = D3D10_TEXTURE_ADDRESS_CLAMP;
|
||||
desc.AddressW = D3D10_TEXTURE_ADDRESS_CLAMP;
|
||||
desc.MipLODBias = 0.f;
|
||||
desc.ComparisonFunc = D3D10_COMPARISON_ALWAYS;
|
||||
desc.MinLOD = 0.f;
|
||||
desc.MaxLOD = 0.f;
|
||||
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
|
||||
}
|
||||
|
||||
ImGui_ImplDX10_CreateFontsTexture();
|
||||
|
||||
return true;
|
||||
@@ -520,8 +544,9 @@ void ImGui_ImplDX10_InvalidateDeviceObjects()
|
||||
if (!bd->pd3dDevice)
|
||||
return;
|
||||
|
||||
ImGui_ImplDX10_DestroyFontsTexture();
|
||||
|
||||
if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = nullptr; }
|
||||
if (bd->pFontTextureView) { bd->pFontTextureView->Release(); bd->pFontTextureView = nullptr; ImGui::GetIO().Fonts->SetTexID(0); } // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||
if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = nullptr; }
|
||||
@@ -536,6 +561,7 @@ void ImGui_ImplDX10_InvalidateDeviceObjects()
|
||||
bool ImGui_ImplDX10_Init(ID3D10Device* device)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
@@ -560,8 +586,8 @@ bool ImGui_ImplDX10_Init(ID3D10Device* device)
|
||||
if (pDXGIAdapter) pDXGIAdapter->Release();
|
||||
bd->pd3dDevice->AddRef();
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplDX10_InitPlatformInterface();
|
||||
ImGui_ImplDX10_InitMultiViewportSupport();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -571,21 +597,22 @@ void ImGui_ImplDX10_Shutdown()
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplDX10_ShutdownPlatformInterface();
|
||||
ImGui_ImplDX10_ShutdownMultiViewportSupport();
|
||||
ImGui_ImplDX10_InvalidateDeviceObjects();
|
||||
if (bd->pFactory) { bd->pFactory->Release(); }
|
||||
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasViewports);
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
void ImGui_ImplDX10_NewFrame()
|
||||
{
|
||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplDX10_Init()?");
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX10_Init()?");
|
||||
|
||||
if (!bd->pFontSampler)
|
||||
if (!bd->pVertexShader)
|
||||
ImGui_ImplDX10_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
@@ -697,7 +724,7 @@ static void ImGui_ImplDX10_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
vd->SwapChain->Present(0, 0); // Present without vsync
|
||||
}
|
||||
|
||||
void ImGui_ImplDX10_InitPlatformInterface()
|
||||
void ImGui_ImplDX10_InitMultiViewportSupport()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Renderer_CreateWindow = ImGui_ImplDX10_CreateWindow;
|
||||
@@ -707,8 +734,11 @@ void ImGui_ImplDX10_InitPlatformInterface()
|
||||
platform_io.Renderer_SwapBuffers = ImGui_ImplDX10_SwapBuffers;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX10_ShutdownPlatformInterface()
|
||||
void ImGui_ImplDX10_ShutdownMultiViewportSupport()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+23
-4
@@ -3,24 +3,43 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
struct ID3D10Device;
|
||||
struct ID3D10SamplerState;
|
||||
struct ID3D10Buffer;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX10_Init(ID3D10Device* device);
|
||||
IMGUI_IMPL_API void ImGui_ImplDX10_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX10_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data);
|
||||
|
||||
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||
IMGUI_IMPL_API void ImGui_ImplDX10_InvalidateDeviceObjects();
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX10_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX10_InvalidateDeviceObjects();
|
||||
|
||||
// [BETA] Selected render state data shared with callbacks.
|
||||
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplDX10_RenderDrawData() call.
|
||||
// (Please open an issue if you feel you need access to more data)
|
||||
struct ImGui_ImplDX10_RenderState
|
||||
{
|
||||
ID3D10Device* Device;
|
||||
ID3D10SamplerState* SamplerDefault;
|
||||
ID3D10Buffer* VertexConstantBuffer;
|
||||
};
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+155
-121
@@ -3,23 +3,30 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-01-06: DirectX11: Expose VertexConstantBuffer in ImGui_ImplDX11_RenderState. Reset projection matrix in ImDrawCallback_ResetRenderState handler.
|
||||
// 2024-10-07: DirectX11: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||
// 2024-10-07: DirectX11: Expose selected render state in ImGui_ImplDX11_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
// 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer.
|
||||
// 2019-08-01: DirectX11: Fixed code querying the Geometry Shader state (would generally error with Debug layer enabled).
|
||||
// 2019-07-21: DirectX11: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData. Clearing Hull/Domain/Compute shaders without backup/restore.
|
||||
// 2019-07-21: DirectX11: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX11_RenderDrawData. Clearing Hull/Domain/Compute shaders without backup/restore.
|
||||
// 2019-05-29: DirectX11: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
|
||||
// 2019-04-30: DirectX11: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
|
||||
// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile().
|
||||
@@ -33,6 +40,7 @@
|
||||
// 2016-05-07: DirectX11: Disabling depth-write.
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_dx11.h"
|
||||
|
||||
// DirectX
|
||||
@@ -79,11 +87,11 @@ static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData()
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplDX11_InitPlatformInterface();
|
||||
static void ImGui_ImplDX11_ShutdownPlatformInterface();
|
||||
static void ImGui_ImplDX11_InitMultiViewportSupport();
|
||||
static void ImGui_ImplDX11_ShutdownMultiViewportSupport();
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* ctx)
|
||||
static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* device_ctx)
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
|
||||
@@ -95,29 +103,50 @@ static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceC
|
||||
vp.MinDepth = 0.0f;
|
||||
vp.MaxDepth = 1.0f;
|
||||
vp.TopLeftX = vp.TopLeftY = 0;
|
||||
ctx->RSSetViewports(1, &vp);
|
||||
device_ctx->RSSetViewports(1, &vp);
|
||||
|
||||
// Setup orthographic projection matrix into our constant buffer
|
||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||
D3D11_MAPPED_SUBRESOURCE mapped_resource;
|
||||
if (device_ctx->Map(bd->pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) == S_OK)
|
||||
{
|
||||
VERTEX_CONSTANT_BUFFER_DX11* constant_buffer = (VERTEX_CONSTANT_BUFFER_DX11*)mapped_resource.pData;
|
||||
float L = draw_data->DisplayPos.x;
|
||||
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||
float T = draw_data->DisplayPos.y;
|
||||
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
|
||||
float mvp[4][4] =
|
||||
{
|
||||
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.5f, 0.0f },
|
||||
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
|
||||
};
|
||||
memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
|
||||
device_ctx->Unmap(bd->pVertexConstantBuffer, 0);
|
||||
}
|
||||
|
||||
// Setup shader and vertex buffers
|
||||
unsigned int stride = sizeof(ImDrawVert);
|
||||
unsigned int offset = 0;
|
||||
ctx->IASetInputLayout(bd->pInputLayout);
|
||||
ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
|
||||
ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
||||
ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
ctx->VSSetShader(bd->pVertexShader, nullptr, 0);
|
||||
ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
||||
ctx->PSSetShader(bd->pPixelShader, nullptr, 0);
|
||||
ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
|
||||
ctx->GSSetShader(nullptr, nullptr, 0);
|
||||
ctx->HSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
ctx->DSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
ctx->CSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
device_ctx->IASetInputLayout(bd->pInputLayout);
|
||||
device_ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
|
||||
device_ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
||||
device_ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
device_ctx->VSSetShader(bd->pVertexShader, nullptr, 0);
|
||||
device_ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
||||
device_ctx->PSSetShader(bd->pPixelShader, nullptr, 0);
|
||||
device_ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
|
||||
device_ctx->GSSetShader(nullptr, nullptr, 0);
|
||||
device_ctx->HSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
device_ctx->DSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
device_ctx->CSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
|
||||
// Setup blend state
|
||||
// Setup render state
|
||||
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||
ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
|
||||
ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0);
|
||||
ctx->RSSetState(bd->pRasterizerState);
|
||||
device_ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
|
||||
device_ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0);
|
||||
device_ctx->RSSetState(bd->pRasterizerState);
|
||||
}
|
||||
|
||||
// Render function
|
||||
@@ -128,7 +157,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
return;
|
||||
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
ID3D11DeviceContext* ctx = bd->pd3dDeviceContext;
|
||||
ID3D11DeviceContext* device = bd->pd3dDeviceContext;
|
||||
|
||||
// Create and grow vertex/index buffers if needed
|
||||
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
||||
@@ -161,44 +190,22 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
|
||||
// Upload vertex/index data into a single contiguous GPU buffer
|
||||
D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource;
|
||||
if (ctx->Map(bd->pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
|
||||
if (device->Map(bd->pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
|
||||
return;
|
||||
if (ctx->Map(bd->pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK)
|
||||
if (device->Map(bd->pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK)
|
||||
return;
|
||||
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData;
|
||||
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += cmd_list->VtxBuffer.Size;
|
||||
idx_dst += cmd_list->IdxBuffer.Size;
|
||||
}
|
||||
ctx->Unmap(bd->pVB, 0);
|
||||
ctx->Unmap(bd->pIB, 0);
|
||||
|
||||
// Setup orthographic projection matrix into our constant buffer
|
||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mapped_resource;
|
||||
if (ctx->Map(bd->pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
|
||||
return;
|
||||
VERTEX_CONSTANT_BUFFER_DX11* constant_buffer = (VERTEX_CONSTANT_BUFFER_DX11*)mapped_resource.pData;
|
||||
float L = draw_data->DisplayPos.x;
|
||||
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||
float T = draw_data->DisplayPos.y;
|
||||
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
|
||||
float mvp[4][4] =
|
||||
{
|
||||
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.5f, 0.0f },
|
||||
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
|
||||
};
|
||||
memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
|
||||
ctx->Unmap(bd->pVertexConstantBuffer, 0);
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
idx_dst += draw_list->IdxBuffer.Size;
|
||||
}
|
||||
device->Unmap(bd->pVB, 0);
|
||||
device->Unmap(bd->pIB, 0);
|
||||
|
||||
// Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
|
||||
struct BACKUP_DX11_STATE
|
||||
@@ -227,26 +234,35 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
};
|
||||
BACKUP_DX11_STATE old = {};
|
||||
old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
|
||||
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
|
||||
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
|
||||
ctx->RSGetState(&old.RS);
|
||||
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
|
||||
ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
|
||||
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
|
||||
ctx->PSGetSamplers(0, 1, &old.PSSampler);
|
||||
device->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
|
||||
device->RSGetViewports(&old.ViewportsCount, old.Viewports);
|
||||
device->RSGetState(&old.RS);
|
||||
device->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
|
||||
device->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
|
||||
device->PSGetShaderResources(0, 1, &old.PSShaderResource);
|
||||
device->PSGetSamplers(0, 1, &old.PSSampler);
|
||||
old.PSInstancesCount = old.VSInstancesCount = old.GSInstancesCount = 256;
|
||||
ctx->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount);
|
||||
ctx->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount);
|
||||
ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
|
||||
ctx->GSGetShader(&old.GS, old.GSInstances, &old.GSInstancesCount);
|
||||
device->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount);
|
||||
device->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount);
|
||||
device->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
|
||||
device->GSGetShader(&old.GS, old.GSInstances, &old.GSInstancesCount);
|
||||
|
||||
ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology);
|
||||
ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
|
||||
ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
|
||||
ctx->IAGetInputLayout(&old.InputLayout);
|
||||
device->IAGetPrimitiveTopology(&old.PrimitiveTopology);
|
||||
device->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
|
||||
device->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
|
||||
device->IAGetInputLayout(&old.InputLayout);
|
||||
|
||||
// Setup desired DX state
|
||||
ImGui_ImplDX11_SetupRenderState(draw_data, ctx);
|
||||
ImGui_ImplDX11_SetupRenderState(draw_data, device);
|
||||
|
||||
// Setup render state structure (for callbacks and custom texture bindings)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
ImGui_ImplDX11_RenderState render_state;
|
||||
render_state.Device = bd->pd3dDevice;
|
||||
render_state.DeviceContext = bd->pd3dDeviceContext;
|
||||
render_state.SamplerDefault = bd->pFontSampler;
|
||||
render_state.VertexConstantBuffer = bd->pVertexConstantBuffer;
|
||||
platform_io.Renderer_RenderState = &render_state;
|
||||
|
||||
// Render command lists
|
||||
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||
@@ -255,18 +271,18 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplDX11_SetupRenderState(draw_data, ctx);
|
||||
ImGui_ImplDX11_SetupRenderState(draw_data, device);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -278,36 +294,37 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
|
||||
// Apply scissor/clipping rectangle
|
||||
const D3D11_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||
ctx->RSSetScissorRects(1, &r);
|
||||
device->RSSetScissorRects(1, &r);
|
||||
|
||||
// Bind texture, Draw
|
||||
ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->GetTexID();
|
||||
ctx->PSSetShaderResources(0, 1, &texture_srv);
|
||||
ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
|
||||
device->PSSetShaderResources(0, 1, &texture_srv);
|
||||
device->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
|
||||
}
|
||||
}
|
||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
||||
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
||||
global_idx_offset += draw_list->IdxBuffer.Size;
|
||||
global_vtx_offset += draw_list->VtxBuffer.Size;
|
||||
}
|
||||
platform_io.Renderer_RenderState = nullptr;
|
||||
|
||||
// Restore modified DX state
|
||||
ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
|
||||
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
|
||||
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
|
||||
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
|
||||
ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
|
||||
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
|
||||
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
|
||||
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
|
||||
device->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
|
||||
device->RSSetViewports(old.ViewportsCount, old.Viewports);
|
||||
device->RSSetState(old.RS); if (old.RS) old.RS->Release();
|
||||
device->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
|
||||
device->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
|
||||
device->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
|
||||
device->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
|
||||
device->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
|
||||
for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release();
|
||||
ctx->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release();
|
||||
ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
|
||||
ctx->GSSetShader(old.GS, old.GSInstances, old.GSInstancesCount); if (old.GS) old.GS->Release();
|
||||
device->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release();
|
||||
device->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
|
||||
device->GSSetShader(old.GS, old.GSInstances, old.GSInstancesCount); if (old.GS) old.GS->Release();
|
||||
for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->Release();
|
||||
ctx->IASetPrimitiveTopology(old.PrimitiveTopology);
|
||||
ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
|
||||
ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
|
||||
ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
|
||||
device->IASetPrimitiveTopology(old.PrimitiveTopology);
|
||||
device->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
|
||||
device->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
|
||||
device->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_CreateFontsTexture()
|
||||
@@ -354,21 +371,16 @@ static void ImGui_ImplDX11_CreateFontsTexture()
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID((ImTextureID)bd->pFontTextureView);
|
||||
}
|
||||
|
||||
// Create texture sampler
|
||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||
static void ImGui_ImplDX11_DestroyFontsTexture()
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
if (bd->pFontTextureView)
|
||||
{
|
||||
D3D11_SAMPLER_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
desc.MipLODBias = 0.f;
|
||||
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
|
||||
desc.MinLOD = 0.f;
|
||||
desc.MaxLOD = 0.f;
|
||||
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
|
||||
bd->pFontTextureView->Release();
|
||||
bd->pFontTextureView = nullptr;
|
||||
ImGui::GetIO().Fonts->SetTexID(0); // We copied data->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -428,9 +440,9 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
||||
// Create the input layout
|
||||
D3D11_INPUT_ELEMENT_DESC local_layout[] =
|
||||
{
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, pos), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)IM_OFFSETOF(ImDrawVert, col), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, pos), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)offsetof(ImDrawVert, col), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
};
|
||||
if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK)
|
||||
{
|
||||
@@ -521,6 +533,22 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
||||
bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState);
|
||||
}
|
||||
|
||||
// Create texture sampler
|
||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||
{
|
||||
D3D11_SAMPLER_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||
desc.MipLODBias = 0.f;
|
||||
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
|
||||
desc.MinLOD = 0.f;
|
||||
desc.MaxLOD = 0.f;
|
||||
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
|
||||
}
|
||||
|
||||
ImGui_ImplDX11_CreateFontsTexture();
|
||||
|
||||
return true;
|
||||
@@ -532,8 +560,9 @@ void ImGui_ImplDX11_InvalidateDeviceObjects()
|
||||
if (!bd->pd3dDevice)
|
||||
return;
|
||||
|
||||
ImGui_ImplDX11_DestroyFontsTexture();
|
||||
|
||||
if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = nullptr; }
|
||||
if (bd->pFontTextureView) { bd->pFontTextureView->Release(); bd->pFontTextureView = nullptr; ImGui::GetIO().Fonts->SetTexID(0); } // We copied data->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||
if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = nullptr; }
|
||||
@@ -548,6 +577,7 @@ void ImGui_ImplDX11_InvalidateDeviceObjects()
|
||||
bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
@@ -575,8 +605,7 @@ bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co
|
||||
bd->pd3dDevice->AddRef();
|
||||
bd->pd3dDeviceContext->AddRef();
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplDX11_InitPlatformInterface();
|
||||
ImGui_ImplDX11_InitMultiViewportSupport();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -587,20 +616,21 @@ void ImGui_ImplDX11_Shutdown()
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplDX11_ShutdownPlatformInterface();
|
||||
ImGui_ImplDX11_ShutdownMultiViewportSupport();
|
||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
if (bd->pFactory) { bd->pFactory->Release(); }
|
||||
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||
if (bd->pd3dDeviceContext) { bd->pd3dDeviceContext->Release(); }
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasViewports);
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
void ImGui_ImplDX11_NewFrame()
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplDX11_Init()?");
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX11_Init()?");
|
||||
|
||||
if (!bd->pFontSampler)
|
||||
ImGui_ImplDX11_CreateDeviceObjects();
|
||||
@@ -714,7 +744,7 @@ static void ImGui_ImplDX11_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
vd->SwapChain->Present(0, 0); // Present without vsync
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_InitPlatformInterface()
|
||||
static void ImGui_ImplDX11_InitMultiViewportSupport()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Renderer_CreateWindow = ImGui_ImplDX11_CreateWindow;
|
||||
@@ -724,7 +754,11 @@ static void ImGui_ImplDX11_InitPlatformInterface()
|
||||
platform_io.Renderer_SwapBuffers = ImGui_ImplDX11_SwapBuffers;
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_ShutdownPlatformInterface()
|
||||
static void ImGui_ImplDX11_ShutdownMultiViewportSupport()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+25
-4
@@ -3,25 +3,46 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
struct ID3D11Device;
|
||||
struct ID3D11DeviceContext;
|
||||
struct ID3D11SamplerState;
|
||||
struct ID3D11Buffer;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context);
|
||||
IMGUI_IMPL_API void ImGui_ImplDX11_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data);
|
||||
|
||||
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||
IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
|
||||
// [BETA] Selected render state data shared with callbacks.
|
||||
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplDX11_RenderDrawData() call.
|
||||
// (Please open an issue if you feel you need access to more data)
|
||||
struct ImGui_ImplDX11_RenderState
|
||||
{
|
||||
ID3D11Device* Device;
|
||||
ID3D11DeviceContext* DeviceContext;
|
||||
ID3D11SamplerState* SamplerDefault;
|
||||
ID3D11Buffer* VertexConstantBuffer;
|
||||
};
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+182
-105
@@ -3,26 +3,33 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// FIXME: The transition from removing a viewport and moving the window in an existing hosted viewport tends to flicker.
|
||||
|
||||
// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
|
||||
// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
|
||||
// To build this on 32-bit systems:
|
||||
// - [Solution 1] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'ImTextureID=ImU64' (this is what we do in the 'example_win32_direct12/example_win32_direct12.vcxproj' project file)
|
||||
// - [Solution 2] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'IMGUI_USER_CONFIG="my_imgui_config.h"' and inside 'my_imgui_config.h' add '#define ImTextureID ImU64' and as many other options as you like.
|
||||
// - [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!)
|
||||
// - [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in the example_win32_direct12/build_win32.bat file)
|
||||
// The aim of imgui_impl_dx12.h/.cpp is to be usable in your engine without any modification.
|
||||
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-01-15: DirectX12: Texture upload use the command queue provided in ImGui_ImplDX12_InitInfo instead of creating its own.
|
||||
// 2024-12-09: DirectX12: Let user specifies the DepthStencilView format by setting ImGui_ImplDX12_InitInfo::DSVFormat.
|
||||
// 2024-11-15: DirectX12: *BREAKING CHANGE* Changed ImGui_ImplDX12_Init() signature to take a ImGui_ImplDX12_InitInfo struct. Legacy ImGui_ImplDX12_Init() signature is still supported (will obsolete).
|
||||
// 2024-11-15: DirectX12: *BREAKING CHANGE* User is now required to pass function pointers to allocate/free SRV Descriptors. We provide convenience legacy fields to pass a single descriptor, matching the old API, but upcoming features will want multiple.
|
||||
// 2024-10-23: DirectX12: Unmap() call specify written range. The range is informational and may be used by debug tools.
|
||||
// 2024-10-07: DirectX12: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||
// 2024-10-07: DirectX12: Expose selected render state in ImGui_ImplDX12_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||
// 2024-10-07: DirectX12: Compiling with '#define ImTextureID=ImU64' is unnecessary now that dear imgui defaults ImTextureID to u64 instead of void*.
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-05-19: DirectX12: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
@@ -42,6 +49,7 @@
|
||||
// 2018-02-22: Merged into master with all Win32 code synchronized to other examples.
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_dx12.h"
|
||||
|
||||
// DirectX
|
||||
@@ -52,18 +60,30 @@
|
||||
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
||||
#endif
|
||||
|
||||
// DirectX data
|
||||
// DirectX12 data
|
||||
struct ImGui_ImplDX12_RenderBuffers;
|
||||
|
||||
struct ImGui_ImplDX12_Texture
|
||||
{
|
||||
ID3D12Resource* pTextureResource;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE hFontSrvCpuDescHandle;
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE hFontSrvGpuDescHandle;
|
||||
|
||||
ImGui_ImplDX12_Texture() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
struct ImGui_ImplDX12_Data
|
||||
{
|
||||
ImGui_ImplDX12_InitInfo InitInfo;
|
||||
ID3D12Device* pd3dDevice;
|
||||
ID3D12RootSignature* pRootSignature;
|
||||
ID3D12PipelineState* pPipelineState;
|
||||
DXGI_FORMAT RTVFormat;
|
||||
ID3D12Resource* pFontTextureResource;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE hFontSrvCpuDescHandle;
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE hFontSrvGpuDescHandle;
|
||||
DXGI_FORMAT DSVFormat;
|
||||
ID3D12DescriptorHeap* pd3dSrvDescHeap;
|
||||
UINT numFramesInFlight;
|
||||
ImGui_ImplDX12_Texture FontTexture;
|
||||
bool LegacySingleDescriptorUsed;
|
||||
|
||||
ImGui_ImplDX12_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
@@ -167,7 +187,7 @@ static void ImGui_ImplDX12_InitPlatformInterface();
|
||||
static void ImGui_ImplDX12_ShutdownPlatformInterface();
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx, ImGui_ImplDX12_RenderBuffers* fr)
|
||||
static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12GraphicsCommandList* command_list, ImGui_ImplDX12_RenderBuffers* fr)
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
|
||||
@@ -197,7 +217,7 @@ static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12Graphic
|
||||
vp.MinDepth = 0.0f;
|
||||
vp.MaxDepth = 1.0f;
|
||||
vp.TopLeftX = vp.TopLeftY = 0.0f;
|
||||
ctx->RSSetViewports(1, &vp);
|
||||
command_list->RSSetViewports(1, &vp);
|
||||
|
||||
// Bind shader and vertex buffers
|
||||
unsigned int stride = sizeof(ImDrawVert);
|
||||
@@ -207,21 +227,21 @@ static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12Graphic
|
||||
vbv.BufferLocation = fr->VertexBuffer->GetGPUVirtualAddress() + offset;
|
||||
vbv.SizeInBytes = fr->VertexBufferSize * stride;
|
||||
vbv.StrideInBytes = stride;
|
||||
ctx->IASetVertexBuffers(0, 1, &vbv);
|
||||
command_list->IASetVertexBuffers(0, 1, &vbv);
|
||||
D3D12_INDEX_BUFFER_VIEW ibv;
|
||||
memset(&ibv, 0, sizeof(D3D12_INDEX_BUFFER_VIEW));
|
||||
ibv.BufferLocation = fr->IndexBuffer->GetGPUVirtualAddress();
|
||||
ibv.SizeInBytes = fr->IndexBufferSize * sizeof(ImDrawIdx);
|
||||
ibv.Format = sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT;
|
||||
ctx->IASetIndexBuffer(&ibv);
|
||||
ctx->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
ctx->SetPipelineState(bd->pPipelineState);
|
||||
ctx->SetGraphicsRootSignature(bd->pRootSignature);
|
||||
ctx->SetGraphicsRoot32BitConstants(0, 16, &vertex_constant_buffer, 0);
|
||||
command_list->IASetIndexBuffer(&ibv);
|
||||
command_list->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
command_list->SetPipelineState(bd->pPipelineState);
|
||||
command_list->SetGraphicsRootSignature(bd->pRootSignature);
|
||||
command_list->SetGraphicsRoot32BitConstants(0, 16, &vertex_constant_buffer, 0);
|
||||
|
||||
// Setup blend factor
|
||||
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||
ctx->OMSetBlendFactor(blend_factor);
|
||||
command_list->OMSetBlendFactor(blend_factor);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@@ -233,12 +253,13 @@ static inline void SafeRelease(T*& res)
|
||||
}
|
||||
|
||||
// Render function
|
||||
void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* ctx)
|
||||
void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* command_list)
|
||||
{
|
||||
// Avoid rendering when minimized
|
||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||
return;
|
||||
|
||||
// FIXME: We are assuming that this only gets called once per frame!
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)draw_data->OwnerViewport->RendererUserData;
|
||||
vd->FrameIndex++;
|
||||
@@ -293,9 +314,9 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
||||
}
|
||||
|
||||
// Upload vertex/index data into a single contiguous GPU buffer
|
||||
// During Map() we specify a null read range (as per DX12 API, this is informational and for tooling only)
|
||||
void* vtx_resource, *idx_resource;
|
||||
D3D12_RANGE range;
|
||||
memset(&range, 0, sizeof(D3D12_RANGE));
|
||||
D3D12_RANGE range = { 0, 0 };
|
||||
if (fr->VertexBuffer->Map(0, &range, &vtx_resource) != S_OK)
|
||||
return;
|
||||
if (fr->IndexBuffer->Map(0, &range, &idx_resource) != S_OK)
|
||||
@@ -304,17 +325,30 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
||||
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += cmd_list->VtxBuffer.Size;
|
||||
idx_dst += cmd_list->IdxBuffer.Size;
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
idx_dst += draw_list->IdxBuffer.Size;
|
||||
}
|
||||
|
||||
// During Unmap() we specify the written range (as per DX12 API, this is informational and for tooling only)
|
||||
range.End = (SIZE_T)((intptr_t)vtx_dst - (intptr_t)vtx_resource);
|
||||
IM_ASSERT(range.End == draw_data->TotalVtxCount * sizeof(ImDrawVert));
|
||||
fr->VertexBuffer->Unmap(0, &range);
|
||||
range.End = (SIZE_T)((intptr_t)idx_dst - (intptr_t)idx_resource);
|
||||
IM_ASSERT(range.End == draw_data->TotalIdxCount * sizeof(ImDrawIdx));
|
||||
fr->IndexBuffer->Unmap(0, &range);
|
||||
|
||||
// Setup desired DX state
|
||||
ImGui_ImplDX12_SetupRenderState(draw_data, ctx, fr);
|
||||
ImGui_ImplDX12_SetupRenderState(draw_data, command_list, fr);
|
||||
|
||||
// Setup render state structure (for callbacks and custom texture bindings)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
ImGui_ImplDX12_RenderState render_state;
|
||||
render_state.Device = bd->pd3dDevice;
|
||||
render_state.CommandList = command_list;
|
||||
platform_io.Renderer_RenderState = &render_state;
|
||||
|
||||
// Render command lists
|
||||
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||
@@ -323,18 +357,18 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplDX12_SetupRenderState(draw_data, ctx, fr);
|
||||
ImGui_ImplDX12_SetupRenderState(draw_data, command_list, fr);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -344,18 +378,21 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
// Apply Scissor/clipping rectangle, Bind texture, Draw
|
||||
// Apply scissor/clipping rectangle
|
||||
const D3D12_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||
command_list->RSSetScissorRects(1, &r);
|
||||
|
||||
// Bind texture, Draw
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE texture_handle = {};
|
||||
texture_handle.ptr = (UINT64)pcmd->GetTexID();
|
||||
ctx->SetGraphicsRootDescriptorTable(1, texture_handle);
|
||||
ctx->RSSetScissorRects(1, &r);
|
||||
ctx->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||
command_list->SetGraphicsRootDescriptorTable(1, texture_handle);
|
||||
command_list->DrawIndexedInstanced(pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||
}
|
||||
}
|
||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
||||
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
||||
global_idx_offset += draw_list->IdxBuffer.Size;
|
||||
global_vtx_offset += draw_list->VtxBuffer.Size;
|
||||
}
|
||||
platform_io.Renderer_RenderState = nullptr;
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX12_CreateFontsTexture()
|
||||
@@ -368,6 +405,7 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||
|
||||
// Upload texture to graphics system
|
||||
ImGui_ImplDX12_Texture* font_tex = &bd->FontTexture;
|
||||
{
|
||||
D3D12_HEAP_PROPERTIES props;
|
||||
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
|
||||
@@ -393,11 +431,11 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
||||
bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc,
|
||||
D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&pTexture));
|
||||
|
||||
UINT uploadPitch = (width * 4 + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u) & ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u);
|
||||
UINT uploadSize = height * uploadPitch;
|
||||
UINT upload_pitch = (width * 4 + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u) & ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u);
|
||||
UINT upload_size = height * upload_pitch;
|
||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
desc.Alignment = 0;
|
||||
desc.Width = uploadSize;
|
||||
desc.Width = upload_size;
|
||||
desc.Height = 1;
|
||||
desc.DepthOrArraySize = 1;
|
||||
desc.MipLevels = 1;
|
||||
@@ -417,26 +455,28 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
void* mapped = nullptr;
|
||||
D3D12_RANGE range = { 0, uploadSize };
|
||||
D3D12_RANGE range = { 0, upload_size };
|
||||
hr = uploadBuffer->Map(0, &range, &mapped);
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
for (int y = 0; y < height; y++)
|
||||
memcpy((void*) ((uintptr_t) mapped + y * uploadPitch), pixels + y * width * 4, width * 4);
|
||||
memcpy((void*) ((uintptr_t) mapped + y * upload_pitch), pixels + y * width * 4, width * 4);
|
||||
uploadBuffer->Unmap(0, &range);
|
||||
|
||||
D3D12_TEXTURE_COPY_LOCATION srcLocation = {};
|
||||
srcLocation.pResource = uploadBuffer;
|
||||
srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
srcLocation.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
srcLocation.PlacedFootprint.Footprint.Width = width;
|
||||
srcLocation.PlacedFootprint.Footprint.Height = height;
|
||||
srcLocation.PlacedFootprint.Footprint.Depth = 1;
|
||||
srcLocation.PlacedFootprint.Footprint.RowPitch = uploadPitch;
|
||||
|
||||
D3D12_TEXTURE_COPY_LOCATION dstLocation = {};
|
||||
dstLocation.pResource = pTexture;
|
||||
dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
dstLocation.SubresourceIndex = 0;
|
||||
{
|
||||
srcLocation.pResource = uploadBuffer;
|
||||
srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
srcLocation.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
srcLocation.PlacedFootprint.Footprint.Width = width;
|
||||
srcLocation.PlacedFootprint.Footprint.Height = height;
|
||||
srcLocation.PlacedFootprint.Footprint.Depth = 1;
|
||||
srcLocation.PlacedFootprint.Footprint.RowPitch = upload_pitch;
|
||||
|
||||
dstLocation.pResource = pTexture;
|
||||
dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
|
||||
dstLocation.SubresourceIndex = 0;
|
||||
}
|
||||
|
||||
D3D12_RESOURCE_BARRIER barrier = {};
|
||||
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||
@@ -450,18 +490,9 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
||||
hr = bd->pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
HANDLE event = CreateEvent(0, 0, 0, 0);
|
||||
HANDLE event = ::CreateEvent(0, 0, 0, 0);
|
||||
IM_ASSERT(event != nullptr);
|
||||
|
||||
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
|
||||
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||
queueDesc.NodeMask = 1;
|
||||
|
||||
ID3D12CommandQueue* cmdQueue = nullptr;
|
||||
hr = bd->pd3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&cmdQueue));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
ID3D12CommandAllocator* cmdAlloc = nullptr;
|
||||
hr = bd->pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&cmdAlloc));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
@@ -476,17 +507,17 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
||||
hr = cmdList->Close();
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
ID3D12CommandQueue* cmdQueue = bd->InitInfo.CommandQueue;
|
||||
cmdQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&cmdList);
|
||||
hr = cmdQueue->Signal(fence, 1);
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
fence->SetEventOnCompletion(1, event);
|
||||
WaitForSingleObject(event, INFINITE);
|
||||
::WaitForSingleObject(event, INFINITE);
|
||||
|
||||
cmdList->Release();
|
||||
cmdAlloc->Release();
|
||||
cmdQueue->Release();
|
||||
CloseHandle(event);
|
||||
::CloseHandle(event);
|
||||
fence->Release();
|
||||
uploadBuffer->Release();
|
||||
|
||||
@@ -498,21 +529,13 @@ static void ImGui_ImplDX12_CreateFontsTexture()
|
||||
srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
||||
srvDesc.Texture2D.MostDetailedMip = 0;
|
||||
srvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
bd->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, bd->hFontSrvCpuDescHandle);
|
||||
SafeRelease(bd->pFontTextureResource);
|
||||
bd->pFontTextureResource = pTexture;
|
||||
bd->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, font_tex->hFontSrvCpuDescHandle);
|
||||
SafeRelease(font_tex->pTextureResource);
|
||||
font_tex->pTextureResource = pTexture;
|
||||
}
|
||||
|
||||
// Store our identifier
|
||||
// READ THIS IF THE STATIC_ASSERT() TRIGGERS:
|
||||
// - Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
|
||||
// - This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*.
|
||||
// [Solution 1] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'ImTextureID=ImU64' (this is what we do in the 'example_win32_direct12/example_win32_direct12.vcxproj' project file)
|
||||
// [Solution 2] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'IMGUI_USER_CONFIG="my_imgui_config.h"' and inside 'my_imgui_config.h' add '#define ImTextureID ImU64' and as many other options as you like.
|
||||
// [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!)
|
||||
// [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in the example_win32_direct12/build_win32.bat file)
|
||||
static_assert(sizeof(ImTextureID) >= sizeof(bd->hFontSrvGpuDescHandle.ptr), "Can't pack descriptor handle into TexID, 32-bit not supported yet.");
|
||||
io.Fonts->SetTexID((ImTextureID)bd->hFontSrvGpuDescHandle.ptr);
|
||||
io.Fonts->SetTexID((ImTextureID)font_tex->hFontSrvGpuDescHandle.ptr);
|
||||
}
|
||||
|
||||
bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
@@ -548,9 +571,9 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
// Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling.
|
||||
D3D12_STATIC_SAMPLER_DESC staticSampler = {};
|
||||
staticSampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
staticSampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
||||
staticSampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
||||
staticSampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
|
||||
staticSampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||
staticSampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||
staticSampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||
staticSampler.MipLODBias = 0.f;
|
||||
staticSampler.MaxAnisotropy = 0;
|
||||
staticSampler.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
|
||||
@@ -620,6 +643,7 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
psoDesc.SampleMask = UINT_MAX;
|
||||
psoDesc.NumRenderTargets = 1;
|
||||
psoDesc.RTVFormats[0] = bd->RTVFormat;
|
||||
psoDesc.DSVFormat = bd->DSVFormat;
|
||||
psoDesc.SampleDesc.Count = 1;
|
||||
psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
|
||||
|
||||
@@ -663,9 +687,9 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
// Create the input layout
|
||||
static D3D12_INPUT_ELEMENT_DESC local_layout[] =
|
||||
{
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, pos), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, uv), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)IM_OFFSETOF(ImDrawVert, col), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, pos), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, uv), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)offsetof(ImDrawVert, col), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
|
||||
};
|
||||
psoDesc.InputLayout = { local_layout, 3 };
|
||||
}
|
||||
@@ -762,21 +786,34 @@ void ImGui_ImplDX12_InvalidateDeviceObjects()
|
||||
if (!bd || !bd->pd3dDevice)
|
||||
return;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
SafeRelease(bd->pRootSignature);
|
||||
SafeRelease(bd->pPipelineState);
|
||||
SafeRelease(bd->pFontTextureResource);
|
||||
io.Fonts->SetTexID(0); // We copied bd->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
|
||||
// Free SRV descriptor used by texture
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplDX12_Texture* font_tex = &bd->FontTexture;
|
||||
bd->InitInfo.SrvDescriptorFreeFn(&bd->InitInfo, font_tex->hFontSrvCpuDescHandle, font_tex->hFontSrvGpuDescHandle);
|
||||
SafeRelease(font_tex->pTextureResource);
|
||||
io.Fonts->SetTexID(0); // We copied bd->hFontSrvGpuDescHandle to io.Fonts->TexID so let's clear that as well.
|
||||
}
|
||||
|
||||
bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* cbv_srv_heap,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle)
|
||||
bool ImGui_ImplDX12_Init(ImGui_ImplDX12_InitInfo* init_info)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplDX12_Data* bd = IM_NEW(ImGui_ImplDX12_Data)();
|
||||
bd->InitInfo = *init_info; // Deep copy
|
||||
init_info = &bd->InitInfo;
|
||||
|
||||
bd->pd3dDevice = init_info->Device;
|
||||
bd->RTVFormat = init_info->RTVFormat;
|
||||
bd->DSVFormat = init_info->DSVFormat;
|
||||
bd->numFramesInFlight = init_info->NumFramesInFlight;
|
||||
bd->pd3dSrvDescHeap = init_info->SrvDescriptorHeap;
|
||||
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_dx12";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
@@ -784,21 +821,56 @@ bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FO
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplDX12_InitPlatformInterface();
|
||||
|
||||
bd->pd3dDevice = device;
|
||||
bd->RTVFormat = rtv_format;
|
||||
bd->hFontSrvCpuDescHandle = font_srv_cpu_desc_handle;
|
||||
bd->hFontSrvGpuDescHandle = font_srv_gpu_desc_handle;
|
||||
bd->numFramesInFlight = num_frames_in_flight;
|
||||
bd->pd3dSrvDescHeap = cbv_srv_heap;
|
||||
|
||||
// Create a dummy ImGui_ImplDX12_ViewportData holder for the main viewport,
|
||||
// Since this is created and managed by the application, we will only use the ->Resources[] fields.
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
main_viewport->RendererUserData = IM_NEW(ImGui_ImplDX12_ViewportData)(bd->numFramesInFlight);
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
if (init_info->SrvDescriptorAllocFn == nullptr)
|
||||
{
|
||||
// Wrap legacy behavior of passing space for a single descriptor
|
||||
IM_ASSERT(init_info->LegacySingleSrvCpuDescriptor.ptr != 0 && init_info->LegacySingleSrvGpuDescriptor.ptr != 0);
|
||||
init_info->SrvDescriptorAllocFn = [](ImGui_ImplDX12_InitInfo*, D3D12_CPU_DESCRIPTOR_HANDLE* out_cpu_handle, D3D12_GPU_DESCRIPTOR_HANDLE* out_gpu_handle)
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
IM_ASSERT(bd->LegacySingleDescriptorUsed == false);
|
||||
*out_cpu_handle = bd->InitInfo.LegacySingleSrvCpuDescriptor;
|
||||
*out_gpu_handle = bd->InitInfo.LegacySingleSrvGpuDescriptor;
|
||||
bd->LegacySingleDescriptorUsed = true;
|
||||
};
|
||||
init_info->SrvDescriptorFreeFn = [](ImGui_ImplDX12_InitInfo*, D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_GPU_DESCRIPTOR_HANDLE)
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
IM_ASSERT(bd->LegacySingleDescriptorUsed == true);
|
||||
bd->LegacySingleDescriptorUsed = false;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
// Allocate 1 SRV descriptor for the font texture
|
||||
IM_ASSERT(init_info->SrvDescriptorAllocFn != nullptr && init_info->SrvDescriptorFreeFn != nullptr);
|
||||
init_info->SrvDescriptorAllocFn(&bd->InitInfo, &bd->FontTexture.hFontSrvCpuDescHandle, &bd->FontTexture.hFontSrvGpuDescHandle);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
// Legacy initialization API Obsoleted in 1.91.5
|
||||
// font_srv_cpu_desc_handle and font_srv_gpu_desc_handle are handles to a single SRV descriptor to use for the internal font texture, they must be in 'srv_descriptor_heap'
|
||||
bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* srv_descriptor_heap, D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle)
|
||||
{
|
||||
ImGui_ImplDX12_InitInfo init_info;
|
||||
init_info.Device = device;
|
||||
init_info.NumFramesInFlight = num_frames_in_flight;
|
||||
init_info.RTVFormat = rtv_format;
|
||||
init_info.SrvDescriptorHeap = srv_descriptor_heap;
|
||||
init_info.LegacySingleSrvCpuDescriptor = font_srv_cpu_desc_handle;
|
||||
init_info.LegacySingleSrvGpuDescriptor = font_srv_gpu_desc_handle;;
|
||||
return ImGui_ImplDX12_Init(&init_info);
|
||||
}
|
||||
#endif
|
||||
|
||||
void ImGui_ImplDX12_Shutdown()
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
@@ -822,13 +894,14 @@ void ImGui_ImplDX12_Shutdown()
|
||||
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasViewports);
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
void ImGui_ImplDX12_NewFrame()
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplDX12_Init()?");
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX12_Init()?");
|
||||
|
||||
if (!bd->pPipelineState)
|
||||
ImGui_ImplDX12_CreateDeviceObjects();
|
||||
@@ -894,7 +967,7 @@ static void ImGui_ImplDX12_CreateWindow(ImGuiViewport* viewport)
|
||||
sd1.SampleDesc.Quality = 0;
|
||||
sd1.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
sd1.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
|
||||
sd1.Scaling = DXGI_SCALING_STRETCH;
|
||||
sd1.Scaling = DXGI_SCALING_NONE;
|
||||
sd1.Stereo = FALSE;
|
||||
|
||||
IDXGIFactory4* dxgi_factory = nullptr;
|
||||
@@ -1073,3 +1146,7 @@ void ImGui_ImplDX12_ShutdownPlatformInterface()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+53
-17
@@ -3,37 +3,73 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'.
|
||||
// See imgui_impl_dx12.cpp file for details.
|
||||
// The aim of imgui_impl_dx12.h/.cpp is to be usable in your engine without any modification.
|
||||
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include <dxgiformat.h> // DXGI_FORMAT
|
||||
#include <d3d12.h> // D3D12_CPU_DESCRIPTOR_HANDLE
|
||||
|
||||
struct ID3D12Device;
|
||||
struct ID3D12DescriptorHeap;
|
||||
struct ID3D12GraphicsCommandList;
|
||||
struct D3D12_CPU_DESCRIPTOR_HANDLE;
|
||||
struct D3D12_GPU_DESCRIPTOR_HANDLE;
|
||||
// Initialization data, for ImGui_ImplDX12_Init()
|
||||
struct ImGui_ImplDX12_InitInfo
|
||||
{
|
||||
ID3D12Device* Device;
|
||||
ID3D12CommandQueue* CommandQueue;
|
||||
int NumFramesInFlight;
|
||||
DXGI_FORMAT RTVFormat; // RenderTarget format.
|
||||
DXGI_FORMAT DSVFormat; // DepthStencilView format.
|
||||
void* UserData;
|
||||
|
||||
// cmd_list is the command list that the implementation will use to render imgui draw lists.
|
||||
// Before calling the render function, caller must prepare cmd_list by resetting it and setting the appropriate
|
||||
// render target and descriptor heap that contains font_srv_cpu_desc_handle/font_srv_gpu_desc_handle.
|
||||
// font_srv_cpu_desc_handle and font_srv_gpu_desc_handle are handles to a single SRV descriptor to use for the internal font texture.
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* cbv_srv_heap,
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle);
|
||||
// Allocating SRV descriptors for textures is up to the application, so we provide callbacks.
|
||||
// (current version of the backend will only allocate one descriptor, future versions will need to allocate more)
|
||||
ID3D12DescriptorHeap* SrvDescriptorHeap;
|
||||
void (*SrvDescriptorAllocFn)(ImGui_ImplDX12_InitInfo* info, D3D12_CPU_DESCRIPTOR_HANDLE* out_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE* out_gpu_desc_handle);
|
||||
void (*SrvDescriptorFreeFn)(ImGui_ImplDX12_InitInfo* info, D3D12_CPU_DESCRIPTOR_HANDLE cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE gpu_desc_handle);
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE LegacySingleSrvCpuDescriptor; // To facilitate transition from single descriptor to allocator callback, you may use those.
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE LegacySingleSrvGpuDescriptor;
|
||||
#endif
|
||||
|
||||
ImGui_ImplDX12_InitInfo() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX12_Init(ImGui_ImplDX12_InitInfo* info);
|
||||
IMGUI_IMPL_API void ImGui_ImplDX12_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX12_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* graphics_command_list);
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
// Legacy initialization API Obsoleted in 1.91.5
|
||||
// font_srv_cpu_desc_handle and font_srv_gpu_desc_handle are handles to a single SRV descriptor to use for the internal font texture, they must be in 'srv_descriptor_heap'
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* srv_descriptor_heap, D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle);
|
||||
#endif
|
||||
|
||||
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||
IMGUI_IMPL_API void ImGui_ImplDX12_InvalidateDeviceObjects();
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX12_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX12_InvalidateDeviceObjects();
|
||||
|
||||
// [BETA] Selected render state data shared with callbacks.
|
||||
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplDX12_RenderDrawData() call.
|
||||
// (Please open an issue if you feel you need access to more data)
|
||||
struct ImGui_ImplDX12_RenderState
|
||||
{
|
||||
ID3D12Device* Device;
|
||||
ID3D12GraphicsCommandList* CommandList;
|
||||
};
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+148
-104
@@ -3,17 +3,23 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: IMGUI_USE_BGRA_PACKED_COLOR support, as this is the optimal color encoding for DirectX9.
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-10-07: DirectX9: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||
// 2024-02-12: DirectX9: Using RGBA format when supported by the driver to avoid CPU side conversion. (#6575)
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-06-25: DirectX9: Explicitly disable texture state stages after >= 1.
|
||||
@@ -34,6 +40,7 @@
|
||||
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_dx9.h"
|
||||
|
||||
// DirectX
|
||||
@@ -48,6 +55,7 @@ struct ImGui_ImplDX9_Data
|
||||
LPDIRECT3DTEXTURE9 FontTexture;
|
||||
int VertexBufferSize;
|
||||
int IndexBufferSize;
|
||||
bool HasRgbaSupport;
|
||||
|
||||
ImGui_ImplDX9_Data() { memset((void*)this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; }
|
||||
};
|
||||
@@ -74,8 +82,8 @@ static ImGui_ImplDX9_Data* ImGui_ImplDX9_GetBackendData()
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplDX9_InitPlatformInterface();
|
||||
static void ImGui_ImplDX9_ShutdownPlatformInterface();
|
||||
static void ImGui_ImplDX9_InitMultiViewportSupport();
|
||||
static void ImGui_ImplDX9_ShutdownMultiViewportSupport();
|
||||
static void ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows();
|
||||
static void ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows();
|
||||
|
||||
@@ -91,41 +99,45 @@ static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data)
|
||||
vp.Height = (DWORD)draw_data->DisplaySize.y;
|
||||
vp.MinZ = 0.0f;
|
||||
vp.MaxZ = 1.0f;
|
||||
bd->pd3dDevice->SetViewport(&vp);
|
||||
|
||||
LPDIRECT3DDEVICE9 device = bd->pd3dDevice;
|
||||
device->SetViewport(&vp);
|
||||
|
||||
// Setup render state: fixed-pipeline, alpha-blending, no face culling, no depth testing, shade mode (for gradient), bilinear sampling.
|
||||
bd->pd3dDevice->SetPixelShader(nullptr);
|
||||
bd->pd3dDevice->SetVertexShader(nullptr);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_CLIPPING, TRUE);
|
||||
bd->pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
bd->pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
bd->pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
bd->pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
bd->pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
device->SetPixelShader(nullptr);
|
||||
device->SetVertexShader(nullptr);
|
||||
device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
|
||||
device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
|
||||
device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
|
||||
device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
|
||||
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
|
||||
device->SetRenderState(D3DRS_ZENABLE, FALSE);
|
||||
device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
|
||||
device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
|
||||
device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
|
||||
device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
|
||||
device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
|
||||
device->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE);
|
||||
device->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_INVSRCALPHA);
|
||||
device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
|
||||
device->SetRenderState(D3DRS_FOGENABLE, FALSE);
|
||||
device->SetRenderState(D3DRS_RANGEFOGENABLE, FALSE);
|
||||
device->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
|
||||
device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
|
||||
device->SetRenderState(D3DRS_CLIPPING, TRUE);
|
||||
device->SetRenderState(D3DRS_LIGHTING, FALSE);
|
||||
device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
|
||||
device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
|
||||
device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
|
||||
device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
|
||||
device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
|
||||
device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
device->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
|
||||
device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
|
||||
// Setup orthographic projection matrix
|
||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||
@@ -143,9 +155,9 @@ static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data)
|
||||
0.0f, 0.0f, 0.5f, 0.0f,
|
||||
(L+R)/(L-R), (T+B)/(B-T), 0.5f, 1.0f
|
||||
} } };
|
||||
bd->pd3dDevice->SetTransform(D3DTS_WORLD, &mat_identity);
|
||||
bd->pd3dDevice->SetTransform(D3DTS_VIEW, &mat_identity);
|
||||
bd->pd3dDevice->SetTransform(D3DTS_PROJECTION, &mat_projection);
|
||||
device->SetTransform(D3DTS_WORLD, &mat_identity);
|
||||
device->SetTransform(D3DTS_VIEW, &mat_identity);
|
||||
device->SetTransform(D3DTS_PROJECTION, &mat_projection);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,51 +168,53 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||
return;
|
||||
|
||||
// Create and grow buffers if needed
|
||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||
LPDIRECT3DDEVICE9 device = bd->pd3dDevice;
|
||||
|
||||
// Create and grow buffers if needed
|
||||
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
||||
{
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||
if (bd->pd3dDevice->CreateVertexBuffer(bd->VertexBufferSize * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &bd->pVB, nullptr) < 0)
|
||||
if (device->CreateVertexBuffer(bd->VertexBufferSize * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &bd->pVB, nullptr) < 0)
|
||||
return;
|
||||
}
|
||||
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
||||
{
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||
if (bd->pd3dDevice->CreateIndexBuffer(bd->IndexBufferSize * sizeof(ImDrawIdx), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, sizeof(ImDrawIdx) == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32, D3DPOOL_DEFAULT, &bd->pIB, nullptr) < 0)
|
||||
if (device->CreateIndexBuffer(bd->IndexBufferSize * sizeof(ImDrawIdx), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, sizeof(ImDrawIdx) == 2 ? D3DFMT_INDEX16 : D3DFMT_INDEX32, D3DPOOL_DEFAULT, &bd->pIB, nullptr) < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
// Backup the DX9 state
|
||||
IDirect3DStateBlock9* d3d9_state_block = nullptr;
|
||||
if (bd->pd3dDevice->CreateStateBlock(D3DSBT_ALL, &d3d9_state_block) < 0)
|
||||
IDirect3DStateBlock9* state_block = nullptr;
|
||||
if (device->CreateStateBlock(D3DSBT_ALL, &state_block) < 0)
|
||||
return;
|
||||
if (d3d9_state_block->Capture() < 0)
|
||||
if (state_block->Capture() < 0)
|
||||
{
|
||||
d3d9_state_block->Release();
|
||||
state_block->Release();
|
||||
return;
|
||||
}
|
||||
|
||||
// Backup the DX9 transform (DX9 documentation suggests that it is included in the StateBlock but it doesn't appear to)
|
||||
D3DMATRIX last_world, last_view, last_projection;
|
||||
bd->pd3dDevice->GetTransform(D3DTS_WORLD, &last_world);
|
||||
bd->pd3dDevice->GetTransform(D3DTS_VIEW, &last_view);
|
||||
bd->pd3dDevice->GetTransform(D3DTS_PROJECTION, &last_projection);
|
||||
device->GetTransform(D3DTS_WORLD, &last_world);
|
||||
device->GetTransform(D3DTS_VIEW, &last_view);
|
||||
device->GetTransform(D3DTS_PROJECTION, &last_projection);
|
||||
|
||||
// Allocate buffers
|
||||
CUSTOMVERTEX* vtx_dst;
|
||||
ImDrawIdx* idx_dst;
|
||||
if (bd->pVB->Lock(0, (UINT)(draw_data->TotalVtxCount * sizeof(CUSTOMVERTEX)), (void**)&vtx_dst, D3DLOCK_DISCARD) < 0)
|
||||
{
|
||||
d3d9_state_block->Release();
|
||||
state_block->Release();
|
||||
return;
|
||||
}
|
||||
if (bd->pIB->Lock(0, (UINT)(draw_data->TotalIdxCount * sizeof(ImDrawIdx)), (void**)&idx_dst, D3DLOCK_DISCARD) < 0)
|
||||
{
|
||||
bd->pVB->Unlock();
|
||||
d3d9_state_block->Release();
|
||||
state_block->Release();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -210,9 +224,9 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
||||
// 2) to avoid repacking vertices: #define IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT struct ImDrawVert { ImVec2 pos; float z; ImU32 col; ImVec2 uv; }
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_src = cmd_list->VtxBuffer.Data;
|
||||
for (int i = 0; i < cmd_list->VtxBuffer.Size; i++)
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_src = draw_list->VtxBuffer.Data;
|
||||
for (int i = 0; i < draw_list->VtxBuffer.Size; i++)
|
||||
{
|
||||
vtx_dst->pos[0] = vtx_src->pos.x;
|
||||
vtx_dst->pos[1] = vtx_src->pos.y;
|
||||
@@ -223,14 +237,14 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
||||
vtx_dst++;
|
||||
vtx_src++;
|
||||
}
|
||||
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
idx_dst += cmd_list->IdxBuffer.Size;
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
idx_dst += draw_list->IdxBuffer.Size;
|
||||
}
|
||||
bd->pVB->Unlock();
|
||||
bd->pIB->Unlock();
|
||||
bd->pd3dDevice->SetStreamSource(0, bd->pVB, 0, sizeof(CUSTOMVERTEX));
|
||||
bd->pd3dDevice->SetIndices(bd->pIB);
|
||||
bd->pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
|
||||
device->SetStreamSource(0, bd->pVB, 0, sizeof(CUSTOMVERTEX));
|
||||
device->SetIndices(bd->pIB);
|
||||
device->SetFVF(D3DFVF_CUSTOMVERTEX);
|
||||
|
||||
// Setup desired DX state
|
||||
ImGui_ImplDX9_SetupRenderState(draw_data);
|
||||
@@ -242,10 +256,10 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
@@ -253,7 +267,7 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplDX9_SetupRenderState(draw_data);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -263,16 +277,18 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
// Apply Scissor/clipping rectangle, Bind texture, Draw
|
||||
// Apply scissor/clipping rectangle
|
||||
const RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||
device->SetScissorRect(&r);
|
||||
|
||||
// Bind texture, Draw
|
||||
const LPDIRECT3DTEXTURE9 texture = (LPDIRECT3DTEXTURE9)pcmd->GetTexID();
|
||||
bd->pd3dDevice->SetTexture(0, texture);
|
||||
bd->pd3dDevice->SetScissorRect(&r);
|
||||
bd->pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, pcmd->VtxOffset + global_vtx_offset, 0, (UINT)cmd_list->VtxBuffer.Size, pcmd->IdxOffset + global_idx_offset, pcmd->ElemCount / 3);
|
||||
device->SetTexture(0, texture);
|
||||
device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, pcmd->VtxOffset + global_vtx_offset, 0, (UINT)draw_list->VtxBuffer.Size, pcmd->IdxOffset + global_idx_offset, pcmd->ElemCount / 3);
|
||||
}
|
||||
}
|
||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
||||
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
||||
global_idx_offset += draw_list->IdxBuffer.Size;
|
||||
global_vtx_offset += draw_list->VtxBuffer.Size;
|
||||
}
|
||||
|
||||
// When using multi-viewports, it appears that there's an odd logic in DirectX9 which prevent subsequent windows
|
||||
@@ -281,18 +297,37 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
||||
bd->pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 0, 0, 0);
|
||||
|
||||
// Restore the DX9 transform
|
||||
bd->pd3dDevice->SetTransform(D3DTS_WORLD, &last_world);
|
||||
bd->pd3dDevice->SetTransform(D3DTS_VIEW, &last_view);
|
||||
bd->pd3dDevice->SetTransform(D3DTS_PROJECTION, &last_projection);
|
||||
device->SetTransform(D3DTS_WORLD, &last_world);
|
||||
device->SetTransform(D3DTS_VIEW, &last_view);
|
||||
device->SetTransform(D3DTS_PROJECTION, &last_projection);
|
||||
|
||||
// Restore the DX9 state
|
||||
d3d9_state_block->Apply();
|
||||
d3d9_state_block->Release();
|
||||
state_block->Apply();
|
||||
state_block->Release();
|
||||
}
|
||||
|
||||
static bool ImGui_ImplDX9_CheckFormatSupport(LPDIRECT3DDEVICE9 pDevice, D3DFORMAT format)
|
||||
{
|
||||
LPDIRECT3D9 pd3d = nullptr;
|
||||
if (pDevice->GetDirect3D(&pd3d) != D3D_OK)
|
||||
return false;
|
||||
D3DDEVICE_CREATION_PARAMETERS param = {};
|
||||
D3DDISPLAYMODE mode = {};
|
||||
if (pDevice->GetCreationParameters(¶m) != D3D_OK || pDevice->GetDisplayMode(0, &mode) != D3D_OK)
|
||||
{
|
||||
pd3d->Release();
|
||||
return false;
|
||||
}
|
||||
// Font texture should support linear filter, color blend and write to render-target
|
||||
bool support = (pd3d->CheckDeviceFormat(param.AdapterOrdinal, param.DeviceType, mode.Format, D3DUSAGE_DYNAMIC | D3DUSAGE_QUERY_FILTER | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, format)) == D3D_OK;
|
||||
pd3d->Release();
|
||||
return support;
|
||||
}
|
||||
|
||||
bool ImGui_ImplDX9_Init(IDirect3DDevice9* device)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
@@ -304,9 +339,9 @@ bool ImGui_ImplDX9_Init(IDirect3DDevice9* device)
|
||||
|
||||
bd->pd3dDevice = device;
|
||||
bd->pd3dDevice->AddRef();
|
||||
bd->HasRgbaSupport = ImGui_ImplDX9_CheckFormatSupport(bd->pd3dDevice, D3DFMT_A8B8G8R8);
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplDX9_InitPlatformInterface();
|
||||
ImGui_ImplDX9_InitMultiViewportSupport();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -317,14 +352,37 @@ void ImGui_ImplDX9_Shutdown()
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplDX9_ShutdownPlatformInterface();
|
||||
ImGui_ImplDX9_ShutdownMultiViewportSupport();
|
||||
ImGui_ImplDX9_InvalidateDeviceObjects();
|
||||
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasViewports);
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
// Convert RGBA32 to BGRA32 (because RGBA32 is not well supported by DX9 devices)
|
||||
static void ImGui_ImplDX9_CopyTextureRegion(bool tex_use_colors, ImU32* src, int src_pitch, ImU32* dst, int dst_pitch, int w, int h)
|
||||
{
|
||||
#ifndef IMGUI_USE_BGRA_PACKED_COLOR
|
||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||
const bool convert_rgba_to_bgra = (!bd->HasRgbaSupport && tex_use_colors);
|
||||
#else
|
||||
const bool convert_rgba_to_bgra = false;
|
||||
IM_UNUSED(tex_use_colors);
|
||||
#endif
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
ImU32* src_p = (ImU32*)((unsigned char*)src + src_pitch * y);
|
||||
ImU32* dst_p = (ImU32*)((unsigned char*)dst + dst_pitch * y);
|
||||
if (convert_rgba_to_bgra)
|
||||
for (int x = w; x > 0; x--, src_p++, dst_p++) // Convert copy
|
||||
*dst_p = IMGUI_COL_TO_DX9_ARGB(*src_p);
|
||||
else
|
||||
memcpy(dst_p, src_p, w * 4); // Raw copy
|
||||
}
|
||||
}
|
||||
|
||||
static bool ImGui_ImplDX9_CreateFontsTexture()
|
||||
{
|
||||
// Build texture atlas
|
||||
@@ -334,36 +392,18 @@ static bool ImGui_ImplDX9_CreateFontsTexture()
|
||||
int width, height, bytes_per_pixel;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height, &bytes_per_pixel);
|
||||
|
||||
// Convert RGBA32 to BGRA32 (because RGBA32 is not well supported by DX9 devices)
|
||||
#ifndef IMGUI_USE_BGRA_PACKED_COLOR
|
||||
if (io.Fonts->TexPixelsUseColors)
|
||||
{
|
||||
ImU32* dst_start = (ImU32*)ImGui::MemAlloc((size_t)width * height * bytes_per_pixel);
|
||||
for (ImU32* src = (ImU32*)pixels, *dst = dst_start, *dst_end = dst_start + (size_t)width * height; dst < dst_end; src++, dst++)
|
||||
*dst = IMGUI_COL_TO_DX9_ARGB(*src);
|
||||
pixels = (unsigned char*)dst_start;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Upload texture to graphics system
|
||||
bd->FontTexture = nullptr;
|
||||
if (bd->pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bd->FontTexture, nullptr) < 0)
|
||||
if (bd->pd3dDevice->CreateTexture(width, height, 1, D3DUSAGE_DYNAMIC, bd->HasRgbaSupport ? D3DFMT_A8B8G8R8 : D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &bd->FontTexture, nullptr) < 0)
|
||||
return false;
|
||||
D3DLOCKED_RECT tex_locked_rect;
|
||||
if (bd->FontTexture->LockRect(0, &tex_locked_rect, nullptr, 0) != D3D_OK)
|
||||
return false;
|
||||
for (int y = 0; y < height; y++)
|
||||
memcpy((unsigned char*)tex_locked_rect.pBits + (size_t)tex_locked_rect.Pitch * y, pixels + (size_t)width * bytes_per_pixel * y, (size_t)width * bytes_per_pixel);
|
||||
ImGui_ImplDX9_CopyTextureRegion(io.Fonts->TexPixelsUseColors, (ImU32*)pixels, width * bytes_per_pixel, (ImU32*)tex_locked_rect.pBits, (int)tex_locked_rect.Pitch, width, height);
|
||||
bd->FontTexture->UnlockRect(0);
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID((ImTextureID)bd->FontTexture);
|
||||
|
||||
#ifndef IMGUI_USE_BGRA_PACKED_COLOR
|
||||
if (io.Fonts->TexPixelsUseColors)
|
||||
ImGui::MemFree(pixels);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -392,7 +432,7 @@ void ImGui_ImplDX9_InvalidateDeviceObjects()
|
||||
void ImGui_ImplDX9_NewFrame()
|
||||
{
|
||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplDX9_Init()?");
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX9_Init()?");
|
||||
|
||||
if (!bd->FontTexture)
|
||||
ImGui_ImplDX9_CreateDeviceObjects();
|
||||
@@ -506,10 +546,10 @@ static void ImGui_ImplDX9_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData;
|
||||
HRESULT hr = vd->SwapChain->Present(nullptr, nullptr, vd->d3dpp.hDeviceWindow, nullptr, 0);
|
||||
// Let main application handle D3DERR_DEVICELOST by resetting the device.
|
||||
IM_ASSERT(hr == D3D_OK || hr == D3DERR_DEVICELOST);
|
||||
IM_ASSERT(SUCCEEDED(hr) || hr == D3DERR_DEVICELOST);
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX9_InitPlatformInterface()
|
||||
static void ImGui_ImplDX9_InitMultiViewportSupport()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Renderer_CreateWindow = ImGui_ImplDX9_CreateWindow;
|
||||
@@ -519,7 +559,7 @@ static void ImGui_ImplDX9_InitPlatformInterface()
|
||||
platform_io.Renderer_SwapBuffers = ImGui_ImplDX9_SwapBuffers;
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX9_ShutdownPlatformInterface()
|
||||
static void ImGui_ImplDX9_ShutdownMultiViewportSupport()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
@@ -539,3 +579,7 @@ static void ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows()
|
||||
if (platform_io.Viewports[i]->RendererUserData)
|
||||
ImGui_ImplDX9_DestroyWindow(platform_io.Viewports[i]);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+11
-3
@@ -3,19 +3,25 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'LPDIRECT3DTEXTURE9' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: IMGUI_USE_BGRA_PACKED_COLOR support, as this is the optimal color encoding for DirectX9.
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
struct IDirect3DDevice9;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX9_Init(IDirect3DDevice9* device);
|
||||
IMGUI_IMPL_API void ImGui_ImplDX9_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX9_NewFrame();
|
||||
@@ -24,3 +30,5 @@ IMGUI_IMPL_API void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data);
|
||||
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX9_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX9_InvalidateDeviceObjects();
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+289
-116
@@ -6,22 +6,42 @@
|
||||
// Implemented features:
|
||||
// [X] Platform: Clipboard support.
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen (Windows only).
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Resizing cursors requires GLFW 3.4+! Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// Issues:
|
||||
// [ ] Platform: Multi-viewport support: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
// Missing features or Issues:
|
||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// About Emscripten support:
|
||||
// - Emscripten provides its own GLFW (3.2.1) implementation (syntax: "-sUSE_GLFW=3"), but Joystick is broken and several features are not supported (multiple windows, clipboard, timer, etc.)
|
||||
// - A third-party Emscripten GLFW (3.4.0) implementation (syntax: "--use-port=contrib.glfw3") fixes the Joystick issue and implements all relevant features for the browser.
|
||||
// See https://github.com/pongasoft/emscripten-glfw/blob/master/docs/Comparison.md for details.
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-11-05: [Docking] Added Linux workaround for spurious mouse up events emitted while dragging and creating new viewport. (#3158, #7733, #7922)
|
||||
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
||||
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
|
||||
// - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn
|
||||
// - io.PlatformOpenInShellFn -> platform_io.Platform_OpenInShellFn
|
||||
// 2024-07-31: Added ImGui_ImplGlfw_Sleep() helper function for usage by our examples app, since GLFW doesn't provide one.
|
||||
// 2024-07-08: *BREAKING* Renamed ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback to ImGui_ImplGlfw_InstallEmscriptenCallbacks(), added GLFWWindow* parameter.
|
||||
// 2024-07-08: Emscripten: Added support for GLFW3 contrib port (GLFW 3.4.0 features + bug fixes): to enable, replace -sUSE_GLFW=3 with --use-port=contrib.glfw3 (requires emscripten 3.1.59+) (https://github.com/pongasoft/emscripten-glfw)
|
||||
// 2024-07-02: Emscripten: Added io.PlatformOpenInShellFn() handler for Emscripten versions.
|
||||
// 2023-12-19: Emscripten: Added ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback() to register canvas selector and auto-resize GLFW window.
|
||||
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys.
|
||||
// 2023-07-18: Inputs: Revert ignoring mouse data on GLFW_CURSOR_DISABLED as it can be used differently. User may set ImGuiConfigFLags_NoMouse if desired. (#5625, #6609)
|
||||
// 2023-06-12: Accept glfwGetTime() not returning a monotonically increasing value. This seems to happens on some Windows setup when peripherals disconnect, and is likely to also happen on browser + Emscripten. (#6491)
|
||||
// 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen/ImGuiMouseSource_Pen on Windows ONLY, using a custom WndProc hook. (#2702)
|
||||
// 2023-03-16: Inputs: Fixed key modifiers handling on secondary viewports (docking branch). Broken on 2023/01/04. (#6248, #6034)
|
||||
// 2023-03-14: Emscripten: Avoid using glfwGetError() and glfwGetGamepadState() which are not correctly implemented in Emscripten emulation. (#6240)
|
||||
@@ -32,7 +52,7 @@
|
||||
// 2022-10-18: Perform a dummy glfwGetError() read to cancel missing mouse cursors errors. Using GLFW_VERSION_COMBINED directly. (#5785)
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
|
||||
// 2022-09-01: Inputs: Honor GLFW_CURSOR_DISABLED by not setting mouse position.
|
||||
// 2022-09-01: Inputs: Honor GLFW_CURSOR_DISABLED by not setting mouse position *EDIT* Reverted 2023-07-18.
|
||||
// 2022-04-30: Inputs: Fixed ImGui_ImplGlfw_TranslateUntranslatedKey() for lower case letters on OSX.
|
||||
// 2022-03-23: Inputs: Fixed a regression in 1.87 which resulted in keyboard modifiers events being reported incorrectly on Linux/X11.
|
||||
// 2022-02-07: Added ImGui_ImplGlfw_InstallCallbacks()/ImGui_ImplGlfw_RestoreCallbacks() helpers to facilitate user installing callbacks after initializing backend.
|
||||
@@ -69,6 +89,7 @@
|
||||
// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers.
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_glfw.h"
|
||||
|
||||
// Clang warnings with -Weverything
|
||||
@@ -83,17 +104,29 @@
|
||||
|
||||
#ifdef _WIN32
|
||||
#undef APIENTRY
|
||||
#ifndef GLFW_EXPOSE_NATIVE_WIN32
|
||||
#define GLFW_EXPOSE_NATIVE_WIN32
|
||||
#endif
|
||||
#include <GLFW/glfw3native.h> // for glfwGetWin32Window()
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
#ifndef GLFW_EXPOSE_NATIVE_COCOA
|
||||
#define GLFW_EXPOSE_NATIVE_COCOA
|
||||
#endif
|
||||
#include <GLFW/glfw3native.h> // for glfwGetCocoaWindow()
|
||||
#endif
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h> // for usleep()
|
||||
#endif
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
#ifdef EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3
|
||||
#include <GLFW/emscripten_glfw3.h>
|
||||
#else
|
||||
#define EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// We gather version tests as define in order to easily see which features are version-dependent.
|
||||
@@ -102,7 +135,11 @@
|
||||
#define GLFW_HAS_WINDOW_HOVERED (GLFW_VERSION_COMBINED >= 3300) // 3.3+ GLFW_HOVERED
|
||||
#define GLFW_HAS_WINDOW_ALPHA (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwSetWindowOpacity
|
||||
#define GLFW_HAS_PER_MONITOR_DPI (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetMonitorContentScale
|
||||
#if defined(__EMSCRIPTEN__) || defined(__SWITCH__) // no Vulkan support in GLFW for Emscripten or homebrew Nintendo Switch
|
||||
#define GLFW_HAS_VULKAN (0)
|
||||
#else
|
||||
#define GLFW_HAS_VULKAN (GLFW_VERSION_COMBINED >= 3200) // 3.2+ glfwCreateWindowSurface
|
||||
#endif
|
||||
#define GLFW_HAS_FOCUS_WINDOW (GLFW_VERSION_COMBINED >= 3200) // 3.2+ glfwFocusWindow
|
||||
#define GLFW_HAS_FOCUS_ON_SHOW (GLFW_VERSION_COMBINED >= 3300) // 3.3+ GLFW_FOCUS_ON_SHOW
|
||||
#define GLFW_HAS_MONITOR_WORK_AREA (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetMonitorWorkarea
|
||||
@@ -126,7 +163,7 @@ enum GlfwClientApi
|
||||
{
|
||||
GlfwClientApi_Unknown,
|
||||
GlfwClientApi_OpenGL,
|
||||
GlfwClientApi_Vulkan
|
||||
GlfwClientApi_Vulkan,
|
||||
};
|
||||
|
||||
struct ImGui_ImplGlfw_Data
|
||||
@@ -136,11 +173,16 @@ struct ImGui_ImplGlfw_Data
|
||||
double Time;
|
||||
GLFWwindow* MouseWindow;
|
||||
GLFWcursor* MouseCursors[ImGuiMouseCursor_COUNT];
|
||||
bool MouseIgnoreButtonUpWaitForFocusLoss;
|
||||
bool MouseIgnoreButtonUp;
|
||||
ImVec2 LastValidMousePos;
|
||||
GLFWwindow* KeyOwnerWindows[GLFW_KEY_LAST];
|
||||
bool InstalledCallbacks;
|
||||
bool CallbacksChainForAllWindows;
|
||||
bool WantUpdateMonitors;
|
||||
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||
const char* CanvasSelector;
|
||||
#endif
|
||||
|
||||
// Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any.
|
||||
GLFWwindowfocusfun PrevUserCallbackWindowFocus;
|
||||
@@ -152,7 +194,7 @@ struct ImGui_ImplGlfw_Data
|
||||
GLFWcharfun PrevUserCallbackChar;
|
||||
GLFWmonitorfun PrevUserCallbackMonitor;
|
||||
#ifdef _WIN32
|
||||
WNDPROC GlfwWndProc;
|
||||
WNDPROC PrevWndProc;
|
||||
#endif
|
||||
|
||||
ImGui_ImplGlfw_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
@@ -172,23 +214,17 @@ static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_GetBackendData()
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplGlfw_UpdateMonitors();
|
||||
static void ImGui_ImplGlfw_InitPlatformInterface();
|
||||
static void ImGui_ImplGlfw_ShutdownPlatformInterface();
|
||||
static void ImGui_ImplGlfw_InitMultiViewportSupport();
|
||||
static void ImGui_ImplGlfw_ShutdownMultiViewportSupport();
|
||||
|
||||
// Functions
|
||||
static const char* ImGui_ImplGlfw_GetClipboardText(void* user_data)
|
||||
{
|
||||
return glfwGetClipboardString((GLFWwindow*)user_data);
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_SetClipboardText(void* user_data, const char* text)
|
||||
// Not static to allow third-party code to use that if they want to (but undocumented)
|
||||
ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int keycode, int scancode);
|
||||
ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int keycode, int scancode)
|
||||
{
|
||||
glfwSetClipboardString((GLFWwindow*)user_data, text);
|
||||
}
|
||||
|
||||
static ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int key)
|
||||
{
|
||||
switch (key)
|
||||
IM_UNUSED(scancode);
|
||||
switch (keycode)
|
||||
{
|
||||
case GLFW_KEY_TAB: return ImGuiKey_Tab;
|
||||
case GLFW_KEY_LEFT: return ImGuiKey_LeftArrow;
|
||||
@@ -295,6 +331,18 @@ static ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int key)
|
||||
case GLFW_KEY_F10: return ImGuiKey_F10;
|
||||
case GLFW_KEY_F11: return ImGuiKey_F11;
|
||||
case GLFW_KEY_F12: return ImGuiKey_F12;
|
||||
case GLFW_KEY_F13: return ImGuiKey_F13;
|
||||
case GLFW_KEY_F14: return ImGuiKey_F14;
|
||||
case GLFW_KEY_F15: return ImGuiKey_F15;
|
||||
case GLFW_KEY_F16: return ImGuiKey_F16;
|
||||
case GLFW_KEY_F17: return ImGuiKey_F17;
|
||||
case GLFW_KEY_F18: return ImGuiKey_F18;
|
||||
case GLFW_KEY_F19: return ImGuiKey_F19;
|
||||
case GLFW_KEY_F20: return ImGuiKey_F20;
|
||||
case GLFW_KEY_F21: return ImGuiKey_F21;
|
||||
case GLFW_KEY_F22: return ImGuiKey_F22;
|
||||
case GLFW_KEY_F23: return ImGuiKey_F23;
|
||||
case GLFW_KEY_F24: return ImGuiKey_F24;
|
||||
default: return ImGuiKey_None;
|
||||
}
|
||||
}
|
||||
@@ -322,6 +370,10 @@ void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int acti
|
||||
if (bd->PrevUserCallbackMousebutton != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
||||
bd->PrevUserCallbackMousebutton(window, button, action, mods);
|
||||
|
||||
// Workaround for Linux: ignore mouse up events which are following an focus loss following a viewport creation
|
||||
if (bd->MouseIgnoreButtonUp && action == GLFW_RELEASE)
|
||||
return;
|
||||
|
||||
ImGui_ImplGlfw_UpdateKeyModifiers(window);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
@@ -335,7 +387,7 @@ void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yo
|
||||
if (bd->PrevUserCallbackScroll != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
||||
bd->PrevUserCallbackScroll(window, xoffset, yoffset);
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||
// Ignore GLFW events: will be processed in ImGui_ImplEmscripten_WheelCallback().
|
||||
return;
|
||||
#endif
|
||||
@@ -344,9 +396,10 @@ void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yo
|
||||
io.AddMouseWheelEvent((float)xoffset, (float)yoffset);
|
||||
}
|
||||
|
||||
// FIXME: should this be baked into ImGui_ImplGlfw_KeyToImGuiKey()? then what about the values passed to io.SetKeyEventNativeData()?
|
||||
static int ImGui_ImplGlfw_TranslateUntranslatedKey(int key, int scancode)
|
||||
{
|
||||
#if GLFW_HAS_GETKEYNAME && !defined(__EMSCRIPTEN__)
|
||||
#if GLFW_HAS_GETKEYNAME && !defined(EMSCRIPTEN_USE_EMBEDDED_GLFW3)
|
||||
// GLFW 3.1+ attempts to "untranslate" keys, which goes the opposite of what every other framework does, making using lettered shortcuts difficult.
|
||||
// (It had reasons to do so: namely GLFW is/was more likely to be used for WASD-type game controls rather than lettered shortcuts, but IHMO the 3.1 change could have been done differently)
|
||||
// See https://github.com/glfw/glfw/issues/1502 for details.
|
||||
@@ -357,7 +410,7 @@ static int ImGui_ImplGlfw_TranslateUntranslatedKey(int key, int scancode)
|
||||
GLFWerrorfun prev_error_callback = glfwSetErrorCallback(nullptr);
|
||||
const char* key_name = glfwGetKeyName(key, scancode);
|
||||
glfwSetErrorCallback(prev_error_callback);
|
||||
#if GLFW_HAS_GETERROR && !defined(__EMSCRIPTEN__) // Eat errors (see #5908)
|
||||
#if GLFW_HAS_GETERROR && !defined(EMSCRIPTEN_USE_EMBEDDED_GLFW3) // Eat errors (see #5908)
|
||||
(void)glfwGetError(nullptr);
|
||||
#endif
|
||||
if (key_name && key_name[0] != 0 && key_name[1] == 0)
|
||||
@@ -394,7 +447,7 @@ void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int keycode, int scancode, i
|
||||
keycode = ImGui_ImplGlfw_TranslateUntranslatedKey(keycode, scancode);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiKey imgui_key = ImGui_ImplGlfw_KeyToImGuiKey(keycode);
|
||||
ImGuiKey imgui_key = ImGui_ImplGlfw_KeyToImGuiKey(keycode, scancode);
|
||||
io.AddKeyEvent(imgui_key, (action == GLFW_PRESS));
|
||||
io.SetKeyEventNativeData(imgui_key, keycode, scancode); // To support legacy indexing (<1.87 user code)
|
||||
}
|
||||
@@ -405,6 +458,10 @@ void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused)
|
||||
if (bd->PrevUserCallbackWindowFocus != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
||||
bd->PrevUserCallbackWindowFocus(window, focused);
|
||||
|
||||
// Workaround for Linux: when losing focus with MouseIgnoreButtonUpWaitForFocusLoss set, we will temporarily ignore subsequent Mouse Up events
|
||||
bd->MouseIgnoreButtonUp = (bd->MouseIgnoreButtonUpWaitForFocusLoss && focused == 0);
|
||||
bd->MouseIgnoreButtonUpWaitForFocusLoss = false;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.AddFocusEvent(focused != 0);
|
||||
}
|
||||
@@ -414,8 +471,6 @@ void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
if (bd->PrevUserCallbackCursorPos != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
||||
bd->PrevUserCallbackCursorPos(window, x, y);
|
||||
if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
|
||||
return;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
@@ -436,8 +491,6 @@ void ImGui_ImplGlfw_CursorEnterCallback(GLFWwindow* window, int entered)
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
if (bd->PrevUserCallbackCursorEnter != nullptr && ImGui_ImplGlfw_ShouldChainCallback(window))
|
||||
bd->PrevUserCallbackCursorEnter(window, entered);
|
||||
if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
|
||||
return;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (entered)
|
||||
@@ -469,7 +522,7 @@ void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor*, int)
|
||||
bd->WantUpdateMonitors = true;
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||
static EM_BOOL ImGui_ImplEmscripten_WheelCallback(int, const EmscriptenWheelEvent* ev, void*)
|
||||
{
|
||||
// Mimic Emscripten_HandleWheel() in SDL.
|
||||
@@ -488,48 +541,7 @@ static EM_BOOL ImGui_ImplEmscripten_WheelCallback(int, const EmscriptenWheelEven
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
// GLFW doesn't allow to distinguish Mouse vs TouchScreen vs Pen.
|
||||
// Add support for Win32 (based on imgui_impl_win32), because we rely on _TouchScreen info to trickle inputs differently.
|
||||
static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
|
||||
{
|
||||
LPARAM extra_info = ::GetMessageExtraInfo();
|
||||
if ((extra_info & 0xFFFFFF80) == 0xFF515700)
|
||||
return ImGuiMouseSource_Pen;
|
||||
if ((extra_info & 0xFFFFFF80) == 0xFF515780)
|
||||
return ImGuiMouseSource_TouchScreen;
|
||||
return ImGuiMouseSource_Mouse;
|
||||
}
|
||||
static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
switch (msg)
|
||||
{
|
||||
case WM_MOUSEMOVE: case WM_NCMOUSEMOVE:
|
||||
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_LBUTTONUP:
|
||||
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_RBUTTONUP:
|
||||
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: case WM_MBUTTONUP:
|
||||
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: case WM_XBUTTONUP:
|
||||
ImGui::GetIO().AddMouseSourceEvent(GetMouseSourceFromMessageExtraInfo());
|
||||
break;
|
||||
|
||||
// We have submitted https://github.com/glfw/glfw/pull/1568 to allow GLFW to support "transparent inputs".
|
||||
// In the meanwhile we implement custom per-platform workarounds here (FIXME-VIEWPORT: Implement same work-around for Linux/OSX!)
|
||||
#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED
|
||||
case WM_NCHITTEST:
|
||||
{
|
||||
// Let mouse pass-through the window. This will allow the backend to call io.AddMouseViewportEvent() properly (which is OPTIONAL).
|
||||
// The ImGuiViewportFlags_NoInputs flag is set while dragging a viewport, as want to detect the window behind the one we are dragging.
|
||||
// If you cannot easily access those viewport flags from your windowing/event code: you may manually synchronize its state e.g. in
|
||||
// your main loop after calling UpdatePlatformWindows(). Iterate all viewports/platform windows and pass the flag to your windowing system.
|
||||
ImGuiViewport* viewport = (ImGuiViewport*)::GetPropA(hWnd, "IMGUI_VIEWPORT");
|
||||
if (viewport && (viewport->Flags & ImGuiViewportFlags_NoInputs))
|
||||
return HTTRANSPARENT;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return ::CallWindowProc(bd->GlfwWndProc, hWnd, msg, wParam, lParam);
|
||||
}
|
||||
static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
#endif
|
||||
|
||||
void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window)
|
||||
@@ -584,9 +596,18 @@ void ImGui_ImplGlfw_SetCallbacksChainForAllWindows(bool chain_for_all_windows)
|
||||
bd->CallbacksChainForAllWindows = chain_for_all_windows;
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#if EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3 >= 34020240817
|
||||
void ImGui_ImplGlfw_EmscriptenOpenURL(const char* url) { if (url) emscripten::glfw3::OpenURL(url); }
|
||||
#else
|
||||
EM_JS(void, ImGui_ImplGlfw_EmscriptenOpenURL, (const char* url), { url = url ? UTF8ToString(url) : null; if (url) window.open(url, '_blank'); });
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, GlfwClientApi client_api)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
|
||||
//printf("GLFW_VERSION: %d.%d.%d (%d)", GLFW_VERSION_MAJOR, GLFW_VERSION_MINOR, GLFW_VERSION_REVISION, GLFW_VERSION_COMBINED);
|
||||
|
||||
@@ -599,7 +620,7 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
||||
#ifndef __EMSCRIPTEN__
|
||||
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
||||
#endif
|
||||
#if GLFW_HAS_MOUSE_PASSTHROUGH || (GLFW_HAS_WINDOW_HOVERED && defined(_WIN32))
|
||||
#if GLFW_HAS_MOUSE_PASSTHROUGH || GLFW_HAS_WINDOW_HOVERED
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional)
|
||||
#endif
|
||||
|
||||
@@ -607,9 +628,12 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
||||
bd->Time = 0.0;
|
||||
bd->WantUpdateMonitors = true;
|
||||
|
||||
io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText;
|
||||
io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText;
|
||||
io.ClipboardUserData = bd->Window;
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Platform_SetClipboardTextFn = [](ImGuiContext*, const char* text) { glfwSetClipboardString(nullptr, text); };
|
||||
platform_io.Platform_GetClipboardTextFn = [](ImGuiContext*) { return glfwGetClipboardString(nullptr); };
|
||||
#ifdef __EMSCRIPTEN__
|
||||
platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { ImGui_ImplGlfw_EmscriptenOpenURL(url); return true; };
|
||||
#endif
|
||||
|
||||
// Create mouse cursors
|
||||
// (By design, on X11 cursors are user configurable and some cursors may be missing. When a cursor doesn't exist,
|
||||
@@ -640,14 +664,9 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
||||
// Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any.
|
||||
if (install_callbacks)
|
||||
ImGui_ImplGlfw_InstallCallbacks(window);
|
||||
// Register Emscripten Wheel callback to workaround issue in Emscripten GLFW Emulation (#6096)
|
||||
// We intentionally do not check 'if (install_callbacks)' here, as some users may set it to false and call GLFW callback themselves.
|
||||
// FIXME: May break chaining in case user registered their own Emscripten callback?
|
||||
#ifdef __EMSCRIPTEN__
|
||||
emscripten_set_wheel_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, nullptr, false, ImGui_ImplEmscripten_WheelCallback);
|
||||
#endif
|
||||
|
||||
// Update monitors the first time (note: monitor callback are broken in GLFW 3.2 and earlier, see github.com/glfw/glfw/issues/784)
|
||||
// Update monitor a first time during init
|
||||
// (note: monitor callback are broken in GLFW 3.2 and earlier, see github.com/glfw/glfw/issues/784)
|
||||
ImGui_ImplGlfw_UpdateMonitors();
|
||||
glfwSetMonitorCallback(ImGui_ImplGlfw_MonitorCallback);
|
||||
|
||||
@@ -661,14 +680,30 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
||||
#else
|
||||
IM_UNUSED(main_viewport);
|
||||
#endif
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplGlfw_InitPlatformInterface();
|
||||
ImGui_ImplGlfw_InitMultiViewportSupport();
|
||||
|
||||
// Windows: register a WndProc hook so we can intercept some messages.
|
||||
#ifdef _WIN32
|
||||
bd->GlfwWndProc = (WNDPROC)::GetWindowLongPtr((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC);
|
||||
IM_ASSERT(bd->GlfwWndProc != nullptr);
|
||||
::SetWindowLongPtr((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
|
||||
bd->PrevWndProc = (WNDPROC)::GetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC);
|
||||
IM_ASSERT(bd->PrevWndProc != nullptr);
|
||||
::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
|
||||
#endif
|
||||
|
||||
// Emscripten: the same application can run on various platforms, so we detect the Apple platform at runtime
|
||||
// to override io.ConfigMacOSXBehaviors from its default (which is always false in Emscripten).
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#if EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3 >= 34020240817
|
||||
if (emscripten::glfw3::IsRuntimePlatformApple())
|
||||
{
|
||||
ImGui::GetIO().ConfigMacOSXBehaviors = true;
|
||||
|
||||
// Due to how the browser (poorly) handles the Meta Key, this line essentially disables repeats when used.
|
||||
// This means that Meta + V only registers a single key-press, even if the keys are held.
|
||||
// This is a compromise for dealing with this issue in ImGui since ImGui implements key repeat itself.
|
||||
// See https://github.com/pongasoft/emscripten-glfw/blob/v3.4.0.20240817/docs/Usage.md#the-problem-of-the-super-key
|
||||
emscripten::glfw3::SetSuperPlusKeyTimeouts(10, 10);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
bd->ClientApi = client_api;
|
||||
@@ -696,23 +731,28 @@ void ImGui_ImplGlfw_Shutdown()
|
||||
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplGlfw_ShutdownPlatformInterface();
|
||||
ImGui_ImplGlfw_ShutdownMultiViewportSupport();
|
||||
|
||||
if (bd->InstalledCallbacks)
|
||||
ImGui_ImplGlfw_RestoreCallbacks(bd->Window);
|
||||
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||
if (bd->CanvasSelector)
|
||||
emscripten_set_wheel_callback(bd->CanvasSelector, nullptr, false, nullptr);
|
||||
#endif
|
||||
|
||||
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
|
||||
glfwDestroyCursor(bd->MouseCursors[cursor_n]);
|
||||
|
||||
// Windows: register a WndProc hook so we can intercept some messages.
|
||||
// Windows: restore our WndProc hook
|
||||
#ifdef _WIN32
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
::SetWindowLongPtr((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)bd->GlfwWndProc);
|
||||
bd->GlfwWndProc = nullptr;
|
||||
::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)bd->PrevWndProc);
|
||||
bd->PrevWndProc = nullptr;
|
||||
#endif
|
||||
|
||||
io.BackendPlatformName = nullptr;
|
||||
io.BackendPlatformUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport);
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -722,12 +762,6 @@ static void ImGui_ImplGlfw_UpdateMouseData()
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
if (glfwGetInputMode(bd->Window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
||||
return;
|
||||
}
|
||||
|
||||
ImGuiID mouse_viewport_id = 0;
|
||||
const ImVec2 mouse_pos_prev = io.MousePos;
|
||||
for (int n = 0; n < platform_io.Viewports.Size; n++)
|
||||
@@ -735,14 +769,14 @@ static void ImGui_ImplGlfw_UpdateMouseData()
|
||||
ImGuiViewport* viewport = platform_io.Viewports[n];
|
||||
GLFWwindow* window = (GLFWwindow*)viewport->PlatformHandle;
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||
const bool is_window_focused = true;
|
||||
#else
|
||||
const bool is_window_focused = glfwGetWindowAttrib(window, GLFW_FOCUSED) != 0;
|
||||
#endif
|
||||
if (is_window_focused)
|
||||
{
|
||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
|
||||
// When multi-viewports are enabled, all Dear ImGui positions are same as OS positions.
|
||||
if (io.WantSetMousePos)
|
||||
glfwSetCursorPos(window, (double)(mouse_pos_prev.x - viewport->Pos.x), (double)(mouse_pos_prev.y - viewport->Pos.y));
|
||||
@@ -768,7 +802,8 @@ static void ImGui_ImplGlfw_UpdateMouseData()
|
||||
|
||||
// (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering.
|
||||
// If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field and infer the information using its flawed heuristic.
|
||||
// - [X] GLFW >= 3.3 backend ON WINDOWS ONLY does correctly ignore viewports with the _NoInputs flag.
|
||||
// - [X] GLFW >= 3.3 backend ON WINDOWS ONLY does correctly ignore viewports with the _NoInputs flag (since we implement hit via our WndProc hook)
|
||||
// On other platforms we rely on the library fallbacking to its own search when reporting a viewport with _NoInputs flag.
|
||||
// - [!] GLFW <= 3.2 backend CANNOT correctly ignore viewports with the _NoInputs flag, and CANNOT reported Hovered Viewport because of mouse capture.
|
||||
// Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the _NoInputs flag (e.g. when dragging a window
|
||||
// for docking, the viewport has the _NoInputs flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported
|
||||
@@ -776,12 +811,12 @@ static void ImGui_ImplGlfw_UpdateMouseData()
|
||||
// - [X] GLFW backend correctly reports this regardless of another viewport behind focused and dragged from (we need this to find a useful drag and drop target).
|
||||
// FIXME: This is currently only correct on Win32. See what we do below with the WM_NCHITTEST, missing an equivalent for other systems.
|
||||
// See https://github.com/glfw/glfw/issues/1236 if you want to help in making this a GLFW feature.
|
||||
#if GLFW_HAS_MOUSE_PASSTHROUGH || (GLFW_HAS_WINDOW_HOVERED && defined(_WIN32))
|
||||
const bool window_no_input = (viewport->Flags & ImGuiViewportFlags_NoInputs) != 0;
|
||||
#if GLFW_HAS_MOUSE_PASSTHROUGH
|
||||
const bool window_no_input = (viewport->Flags & ImGuiViewportFlags_NoInputs) != 0;
|
||||
glfwSetWindowAttrib(window, GLFW_MOUSE_PASSTHROUGH, window_no_input);
|
||||
#endif
|
||||
if (glfwGetWindowAttrib(window, GLFW_HOVERED) && !window_no_input)
|
||||
#if GLFW_HAS_MOUSE_PASSTHROUGH || GLFW_HAS_WINDOW_HOVERED
|
||||
if (glfwGetWindowAttrib(window, GLFW_HOVERED))
|
||||
mouse_viewport_id = viewport->ID;
|
||||
#else
|
||||
// We cannot use bd->MouseWindow maintained from CursorEnter/Leave callbacks, because it is locked to the window capturing mouse.
|
||||
@@ -828,7 +863,7 @@ static void ImGui_ImplGlfw_UpdateGamepads()
|
||||
return;
|
||||
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
||||
#if GLFW_HAS_GAMEPAD_API && !defined(__EMSCRIPTEN__)
|
||||
#if GLFW_HAS_GAMEPAD_API && !defined(EMSCRIPTEN_USE_EMBEDDED_GLFW3)
|
||||
GLFWgamepadstate gamepad;
|
||||
if (!glfwGetGamepadState(GLFW_JOYSTICK_1, &gamepad))
|
||||
return;
|
||||
@@ -876,10 +911,14 @@ static void ImGui_ImplGlfw_UpdateMonitors()
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
bd->WantUpdateMonitors = false;
|
||||
|
||||
int monitors_count = 0;
|
||||
GLFWmonitor** glfw_monitors = glfwGetMonitors(&monitors_count);
|
||||
if (monitors_count == 0) // Preserve existing monitor list if there are none. Happens on macOS sleeping (#5683)
|
||||
return;
|
||||
|
||||
platform_io.Monitors.resize(0);
|
||||
bd->WantUpdateMonitors = false;
|
||||
for (int n = 0; n < monitors_count; n++)
|
||||
{
|
||||
ImGuiPlatformMonitor monitor;
|
||||
@@ -903,8 +942,11 @@ static void ImGui_ImplGlfw_UpdateMonitors()
|
||||
// Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings, which generally needs to be set in the manifest or at runtime.
|
||||
float x_scale, y_scale;
|
||||
glfwGetMonitorContentScale(glfw_monitors[n], &x_scale, &y_scale);
|
||||
if (x_scale == 0.0f)
|
||||
continue; // Some accessibility applications are declaring virtual monitors with a DPI of 0, see #7902.
|
||||
monitor.DpiScale = x_scale;
|
||||
#endif
|
||||
monitor.PlatformHandle = (void*)glfw_monitors[n]; // [...] GLFW doc states: "guaranteed to be valid only until the monitor configuration changes"
|
||||
platform_io.Monitors.push_back(monitor);
|
||||
}
|
||||
}
|
||||
@@ -913,7 +955,7 @@ void ImGui_ImplGlfw_NewFrame()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplGlfw_InitForXXX()?");
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplGlfw_InitForXXX()?");
|
||||
|
||||
// Setup display size (every frame to accommodate for window resizing)
|
||||
int w, h;
|
||||
@@ -927,10 +969,14 @@ void ImGui_ImplGlfw_NewFrame()
|
||||
ImGui_ImplGlfw_UpdateMonitors();
|
||||
|
||||
// Setup time step
|
||||
// (Accept glfwGetTime() not returning a monotonically increasing value. Seems to happens on disconnecting peripherals and probably on VMs and Emscripten, see #6491, #6189, #6114, #3644)
|
||||
double current_time = glfwGetTime();
|
||||
if (current_time <= bd->Time)
|
||||
current_time = bd->Time + 0.00001f;
|
||||
io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f);
|
||||
bd->Time = current_time;
|
||||
|
||||
bd->MouseIgnoreButtonUp = false;
|
||||
ImGui_ImplGlfw_UpdateMouseData();
|
||||
ImGui_ImplGlfw_UpdateMouseCursor();
|
||||
|
||||
@@ -938,6 +984,69 @@ void ImGui_ImplGlfw_NewFrame()
|
||||
ImGui_ImplGlfw_UpdateGamepads();
|
||||
}
|
||||
|
||||
// GLFW doesn't provide a portable sleep function
|
||||
void ImGui_ImplGlfw_Sleep(int milliseconds)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
::Sleep(milliseconds);
|
||||
#else
|
||||
usleep(milliseconds * 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||
static EM_BOOL ImGui_ImplGlfw_OnCanvasSizeChange(int event_type, const EmscriptenUiEvent* event, void* user_data)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = (ImGui_ImplGlfw_Data*)user_data;
|
||||
double canvas_width, canvas_height;
|
||||
emscripten_get_element_css_size(bd->CanvasSelector, &canvas_width, &canvas_height);
|
||||
glfwSetWindowSize(bd->Window, (int)canvas_width, (int)canvas_height);
|
||||
return true;
|
||||
}
|
||||
|
||||
static EM_BOOL ImGui_ImplEmscripten_FullscreenChangeCallback(int event_type, const EmscriptenFullscreenChangeEvent* event, void* user_data)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = (ImGui_ImplGlfw_Data*)user_data;
|
||||
double canvas_width, canvas_height;
|
||||
emscripten_get_element_css_size(bd->CanvasSelector, &canvas_width, &canvas_height);
|
||||
glfwSetWindowSize(bd->Window, (int)canvas_width, (int)canvas_height);
|
||||
return true;
|
||||
}
|
||||
|
||||
// 'canvas_selector' is a CSS selector. The event listener is applied to the first element that matches the query.
|
||||
// STRING MUST PERSIST FOR THE APPLICATION DURATION. PLEASE USE A STRING LITERAL OR ENSURE POINTER WILL STAY VALID.
|
||||
void ImGui_ImplGlfw_InstallEmscriptenCallbacks(GLFWwindow*, const char* canvas_selector)
|
||||
{
|
||||
IM_ASSERT(canvas_selector != nullptr);
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplGlfw_InitForXXX()?");
|
||||
|
||||
bd->CanvasSelector = canvas_selector;
|
||||
emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, bd, false, ImGui_ImplGlfw_OnCanvasSizeChange);
|
||||
emscripten_set_fullscreenchange_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, bd, false, ImGui_ImplEmscripten_FullscreenChangeCallback);
|
||||
|
||||
// Change the size of the GLFW window according to the size of the canvas
|
||||
ImGui_ImplGlfw_OnCanvasSizeChange(EMSCRIPTEN_EVENT_RESIZE, {}, bd);
|
||||
|
||||
// Register Emscripten Wheel callback to workaround issue in Emscripten GLFW Emulation (#6096)
|
||||
// We intentionally do not check 'if (install_callbacks)' here, as some users may set it to false and call GLFW callback themselves.
|
||||
// FIXME: May break chaining in case user registered their own Emscripten callback?
|
||||
emscripten_set_wheel_callback(bd->CanvasSelector, nullptr, false, ImGui_ImplEmscripten_WheelCallback);
|
||||
}
|
||||
#elif defined(EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3)
|
||||
// When using --use-port=contrib.glfw3 for the GLFW implementation, you can override the behavior of this call
|
||||
// by invoking emscripten_glfw_make_canvas_resizable afterward.
|
||||
// See https://github.com/pongasoft/emscripten-glfw/blob/master/docs/Usage.md#how-to-make-the-canvas-resizable-by-the-user for an explanation
|
||||
void ImGui_ImplGlfw_InstallEmscriptenCallbacks(GLFWwindow* window, const char* canvas_selector)
|
||||
{
|
||||
GLFWwindow* w = (GLFWwindow*)(EM_ASM_INT({ return Module.glfwGetWindow(UTF8ToString($0)); }, canvas_selector));
|
||||
IM_ASSERT(window == w); // Sanity check
|
||||
IM_UNUSED(w);
|
||||
emscripten_glfw_make_canvas_resizable(window, "window", nullptr);
|
||||
}
|
||||
#endif // #ifdef EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
||||
@@ -951,8 +1060,11 @@ struct ImGui_ImplGlfw_ViewportData
|
||||
bool WindowOwned;
|
||||
int IgnoreWindowPosEventFrame;
|
||||
int IgnoreWindowSizeEventFrame;
|
||||
#ifdef _WIN32
|
||||
WNDPROC PrevWndProc;
|
||||
#endif
|
||||
|
||||
ImGui_ImplGlfw_ViewportData() { Window = nullptr; WindowOwned = false; IgnoreWindowSizeEventFrame = IgnoreWindowPosEventFrame = -1; }
|
||||
ImGui_ImplGlfw_ViewportData() { memset((void*)this, 0, sizeof(*this)); IgnoreWindowSizeEventFrame = IgnoreWindowPosEventFrame = -1; }
|
||||
~ImGui_ImplGlfw_ViewportData() { IM_ASSERT(Window == nullptr); }
|
||||
};
|
||||
|
||||
@@ -1004,6 +1116,11 @@ static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport)
|
||||
ImGui_ImplGlfw_ViewportData* vd = IM_NEW(ImGui_ImplGlfw_ViewportData)();
|
||||
viewport->PlatformUserData = vd;
|
||||
|
||||
// Workaround for Linux: ignore mouse up events corresponding to losing focus of the previously focused window (#7733, #3158, #7922)
|
||||
#ifdef __linux__
|
||||
bd->MouseIgnoreButtonUpWaitForFocusLoss = true;
|
||||
#endif
|
||||
|
||||
// GLFW 3.2 unfortunately always set focus on glfwCreateWindow() if GLFW_VISIBLE is set, regardless of GLFW_FOCUSED
|
||||
// With GLFW 3.3, the hint GLFW_FOCUS_ON_SHOW fixes this problem
|
||||
glfwWindowHint(GLFW_VISIBLE, false);
|
||||
@@ -1087,10 +1204,9 @@ static void ImGui_ImplGlfw_ShowWindow(ImGuiViewport* viewport)
|
||||
|
||||
// GLFW hack: install hook for WM_NCHITTEST message handler
|
||||
#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED && defined(_WIN32)
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
::SetPropA(hwnd, "IMGUI_VIEWPORT", viewport);
|
||||
IM_ASSERT(bd->GlfwWndProc == (WNDPROC)::GetWindowLongPtr(hwnd, GWLP_WNDPROC));
|
||||
::SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
|
||||
vd->PrevWndProc = (WNDPROC)::GetWindowLongPtrW(hwnd, GWLP_WNDPROC);
|
||||
::SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
|
||||
#endif
|
||||
|
||||
#if !GLFW_HAS_FOCUS_ON_SHOW
|
||||
@@ -1235,7 +1351,7 @@ static int ImGui_ImplGlfw_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_inst
|
||||
}
|
||||
#endif // GLFW_HAS_VULKAN
|
||||
|
||||
static void ImGui_ImplGlfw_InitPlatformInterface()
|
||||
static void ImGui_ImplGlfw_InitMultiViewportSupport()
|
||||
{
|
||||
// Register platform interface (will be coupled with a renderer interface)
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
@@ -1270,11 +1386,68 @@ static void ImGui_ImplGlfw_InitPlatformInterface()
|
||||
main_viewport->PlatformHandle = (void*)bd->Window;
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_ShutdownPlatformInterface()
|
||||
static void ImGui_ImplGlfw_ShutdownMultiViewportSupport()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// WndProc hook (declared here because we will need access to ImGui_ImplGlfw_ViewportData)
|
||||
#ifdef _WIN32
|
||||
static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
|
||||
{
|
||||
LPARAM extra_info = ::GetMessageExtraInfo();
|
||||
if ((extra_info & 0xFFFFFF80) == 0xFF515700)
|
||||
return ImGuiMouseSource_Pen;
|
||||
if ((extra_info & 0xFFFFFF80) == 0xFF515780)
|
||||
return ImGuiMouseSource_TouchScreen;
|
||||
return ImGuiMouseSource_Mouse;
|
||||
}
|
||||
static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
WNDPROC prev_wndproc = bd->PrevWndProc;
|
||||
ImGuiViewport* viewport = (ImGuiViewport*)::GetPropA(hWnd, "IMGUI_VIEWPORT");
|
||||
if (viewport != NULL)
|
||||
if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData)
|
||||
prev_wndproc = vd->PrevWndProc;
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
// GLFW doesn't allow to distinguish Mouse vs TouchScreen vs Pen.
|
||||
// Add support for Win32 (based on imgui_impl_win32), because we rely on _TouchScreen info to trickle inputs differently.
|
||||
case WM_MOUSEMOVE: case WM_NCMOUSEMOVE:
|
||||
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_LBUTTONUP:
|
||||
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_RBUTTONUP:
|
||||
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: case WM_MBUTTONUP:
|
||||
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: case WM_XBUTTONUP:
|
||||
ImGui::GetIO().AddMouseSourceEvent(GetMouseSourceFromMessageExtraInfo());
|
||||
break;
|
||||
|
||||
// We have submitted https://github.com/glfw/glfw/pull/1568 to allow GLFW to support "transparent inputs".
|
||||
// In the meanwhile we implement custom per-platform workarounds here (FIXME-VIEWPORT: Implement same work-around for Linux/OSX!)
|
||||
#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED
|
||||
case WM_NCHITTEST:
|
||||
{
|
||||
// Let mouse pass-through the window. This will allow the backend to call io.AddMouseViewportEvent() properly (which is OPTIONAL).
|
||||
// The ImGuiViewportFlags_NoInputs flag is set while dragging a viewport, as want to detect the window behind the one we are dragging.
|
||||
// If you cannot easily access those viewport flags from your windowing/event code: you may manually synchronize its state e.g. in
|
||||
// your main loop after calling UpdatePlatformWindows(). Iterate all viewports/platform windows and pass the flag to your windowing system.
|
||||
if (viewport && (viewport->Flags & ImGuiViewportFlags_NoInputs))
|
||||
return HTTRANSPARENT;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return ::CallWindowProcW(prev_wndproc, hWnd, msg, wParam, lParam);
|
||||
}
|
||||
#endif // #ifdef _WIN32
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+22
-7
@@ -6,31 +6,41 @@
|
||||
// Implemented features:
|
||||
// [X] Platform: Clipboard support.
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen (Windows only).
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [x] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange' (note: the resizing cursors requires GLFW 3.4+).
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Resizing cursors requires GLFW 3.4+! Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// Issues:
|
||||
// [ ] Platform: Multi-viewport support: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
// Missing features or Issues:
|
||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
struct GLFWwindow;
|
||||
struct GLFWmonitor;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOpenGL(GLFWwindow* window, bool install_callbacks);
|
||||
IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks);
|
||||
IMGUI_IMPL_API bool ImGui_ImplGlfw_InitForOther(GLFWwindow* window, bool install_callbacks);
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_NewFrame();
|
||||
|
||||
// Emscripten related initialization phase methods (call after ImGui_ImplGlfw_InitForOpenGL)
|
||||
#ifdef __EMSCRIPTEN__
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_InstallEmscriptenCallbacks(GLFWwindow* window, const char* canvas_selector);
|
||||
//static inline void ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback(const char* canvas_selector) { ImGui_ImplGlfw_InstallEmscriptenCallbacks(nullptr, canvas_selector); } } // Renamed in 1.91.0
|
||||
#endif
|
||||
|
||||
// GLFW callbacks install
|
||||
// - When calling Init with 'install_callbacks=true': ImGui_ImplGlfw_InstallCallbacks() is called. GLFW callbacks will be installed for you. They will chain-call user's previously installed callbacks, if any.
|
||||
// - When calling Init with 'install_callbacks=false': GLFW callbacks won't be installed. You will need to call individual function yourself from your own GLFW callbacks.
|
||||
@@ -50,3 +60,8 @@ IMGUI_IMPL_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c);
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor* monitor, int event);
|
||||
|
||||
// GLFW helpers
|
||||
IMGUI_IMPL_API void ImGui_ImplGlfw_Sleep(int milliseconds);
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+17
-7
@@ -6,21 +6,26 @@
|
||||
// !!! Nowadays, prefer using GLFW or SDL instead!
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Partial keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLUT values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// Issues:
|
||||
// [X] Platform: Partial keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLUT values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// Missing features or Issues:
|
||||
// [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I
|
||||
// [ ] Platform: Missing horizontal mouse wheel support.
|
||||
// [ ] Platform: Missing mouse cursor shape/visibility support.
|
||||
// [ ] Platform: Missing clipboard support (not supported by Glut).
|
||||
// [ ] Platform: Missing gamepad support.
|
||||
// [ ] Platform: Missing multi-viewport support (multiple windows).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-04-17: BREAKING: Removed call to ImGui::NewFrame() from ImGui_ImplGLUT_NewFrame(). Needs to be called from the main application loop, like with every other backends.
|
||||
// 2022-09-26: Inputs: Renamed ImGuiKey_ModXXX introduced in 1.87 to ImGuiMod_XXX (old names still supported).
|
||||
// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago) with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
|
||||
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
|
||||
@@ -31,6 +36,7 @@
|
||||
// 2018-03-22: Added GLUT Platform binding.
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_glut.h"
|
||||
#define GL_SILENCE_DEPRECATION
|
||||
#ifdef __APPLE__
|
||||
@@ -162,6 +168,7 @@ static ImGuiKey ImGui_ImplGLUT_KeyToImGuiKey(int key)
|
||||
bool ImGui_ImplGLUT_Init()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
|
||||
#ifdef FREEGLUT
|
||||
io.BackendPlatformName = "imgui_impl_glut (freeglut)";
|
||||
@@ -190,6 +197,8 @@ void ImGui_ImplGLUT_InstallFuncs()
|
||||
|
||||
void ImGui_ImplGLUT_Shutdown()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.BackendPlatformName = nullptr;
|
||||
}
|
||||
|
||||
void ImGui_ImplGLUT_NewFrame()
|
||||
@@ -202,9 +211,6 @@ void ImGui_ImplGLUT_NewFrame()
|
||||
delta_time_ms = 1;
|
||||
io.DeltaTime = delta_time_ms / 1000.0f;
|
||||
g_Time = current_time;
|
||||
|
||||
// Start the frame
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
static void ImGui_ImplGLUT_UpdateKeyModifiers()
|
||||
@@ -298,3 +304,7 @@ void ImGui_ImplGLUT_MotionFunc(int x, int y)
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.AddMousePosEvent((float)x, (float)y);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+13
-5
@@ -6,22 +6,28 @@
|
||||
// !!! Nowadays, prefer using GLFW or SDL instead!
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Partial keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLUT values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// Issues:
|
||||
// [X] Platform: Partial keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLUT values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// Missing features or Issues:
|
||||
// [ ] Platform: GLUT is unable to distinguish e.g. Backspace from CTRL+H or TAB from CTRL+I
|
||||
// [ ] Platform: Missing horizontal mouse wheel support.
|
||||
// [ ] Platform: Missing mouse cursor shape/visibility support.
|
||||
// [ ] Platform: Missing clipboard support (not supported by Glut).
|
||||
// [ ] Platform: Missing gamepad support.
|
||||
// [ ] Platform: Missing multi-viewport support (multiple windows).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#pragma once
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplGLUT_Init();
|
||||
IMGUI_IMPL_API void ImGui_ImplGLUT_InstallFuncs();
|
||||
IMGUI_IMPL_API void ImGui_ImplGLUT_Shutdown();
|
||||
@@ -29,7 +35,7 @@ IMGUI_IMPL_API void ImGui_ImplGLUT_NewFrame();
|
||||
|
||||
// You can call ImGui_ImplGLUT_InstallFuncs() to get all those functions installed automatically,
|
||||
// or call them yourself from your own GLUT handlers. We are using the same weird names as GLUT for consistency..
|
||||
//---------------------------------------- GLUT name --------------------------------------------- Decent Name ---------
|
||||
//------------------------------------ GLUT name ---------------------------------------------- Decent Name ---------
|
||||
IMGUI_IMPL_API void ImGui_ImplGLUT_ReshapeFunc(int w, int h); // ~ ResizeFunc
|
||||
IMGUI_IMPL_API void ImGui_ImplGLUT_MotionFunc(int x, int y); // ~ MouseMoveFunc
|
||||
IMGUI_IMPL_API void ImGui_ImplGLUT_MouseFunc(int button, int state, int x, int y); // ~ MouseButtonFunc
|
||||
@@ -38,3 +44,5 @@ IMGUI_IMPL_API void ImGui_ImplGLUT_KeyboardFunc(unsigned char c, int x, int
|
||||
IMGUI_IMPL_API void ImGui_ImplGLUT_KeyboardUpFunc(unsigned char c, int x, int y); // ~ CharReleasedFunc
|
||||
IMGUI_IMPL_API void ImGui_ImplGLUT_SpecialFunc(int key, int x, int y); // ~ KeyPressedFunc
|
||||
IMGUI_IMPL_API void ImGui_ImplGLUT_SpecialUpFunc(int key, int x, int y); // ~ KeyReleasedFunc
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+13
-3
@@ -3,15 +3,19 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ObjC API
|
||||
@@ -22,6 +26,7 @@
|
||||
@class MTLRenderPassDescriptor;
|
||||
@protocol MTLDevice, MTLCommandBuffer, MTLRenderCommandEncoder;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplMetal_Init(id<MTLDevice> device);
|
||||
IMGUI_IMPL_API void ImGui_ImplMetal_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplMetal_NewFrame(MTLRenderPassDescriptor* renderPassDescriptor);
|
||||
@@ -48,6 +53,7 @@ IMGUI_IMPL_API void ImGui_ImplMetal_DestroyDeviceObjects();
|
||||
#include <Metal/Metal.hpp>
|
||||
#ifndef __OBJC__
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplMetal_Init(MTL::Device* device);
|
||||
IMGUI_IMPL_API void ImGui_ImplMetal_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplMetal_NewFrame(MTL::RenderPassDescriptor* renderPassDescriptor);
|
||||
@@ -63,3 +69,7 @@ IMGUI_IMPL_API void ImGui_ImplMetal_DestroyDeviceObjects();
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+57
-37
@@ -3,17 +3,21 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'MTLTexture' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Metal: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-XX-XX: Metal: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-01-08: Metal: Fixed memory leaks when using metal-cpp (#8276, #8166) or when using multiple contexts (#7419).
|
||||
// 2022-08-23: Metal: Update deprecated property 'sampleCount'->'rasterSampleCount'.
|
||||
// 2022-07-05: Metal: Add dispatch synchronization.
|
||||
// 2022-06-30: Metal: Use __bridge for ARC based systems.
|
||||
@@ -32,13 +36,14 @@
|
||||
// 2018-07-05: Metal: Added new Metal backend implementation.
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_metal.h"
|
||||
#import <time.h>
|
||||
#import <Metal/Metal.h>
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplMetal_InitPlatformInterface();
|
||||
static void ImGui_ImplMetal_ShutdownPlatformInterface();
|
||||
static void ImGui_ImplMetal_InitMultiViewportSupport();
|
||||
static void ImGui_ImplMetal_ShutdownMultiViewportSupport();
|
||||
static void ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows();
|
||||
static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows();
|
||||
|
||||
@@ -80,10 +85,9 @@ struct ImGui_ImplMetal_Data
|
||||
{
|
||||
MetalContext* SharedMetalContext;
|
||||
|
||||
ImGui_ImplMetal_Data() { memset(this, 0, sizeof(*this)); }
|
||||
ImGui_ImplMetal_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
static ImGui_ImplMetal_Data* ImGui_ImplMetal_CreateBackendData() { return IM_NEW(ImGui_ImplMetal_Data)(); }
|
||||
static ImGui_ImplMetal_Data* ImGui_ImplMetal_GetBackendData() { return ImGui::GetCurrentContext() ? (ImGui_ImplMetal_Data*)ImGui::GetIO().BackendRendererUserData : nullptr; }
|
||||
static void ImGui_ImplMetal_DestroyBackendData(){ IM_DELETE(ImGui_ImplMetal_GetBackendData()); }
|
||||
|
||||
@@ -129,8 +133,11 @@ bool ImGui_ImplMetal_CreateDeviceObjects(MTL::Device* device)
|
||||
|
||||
bool ImGui_ImplMetal_Init(id<MTLDevice> device)
|
||||
{
|
||||
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_CreateBackendData();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
ImGui_ImplMetal_Data* bd = IM_NEW(ImGui_ImplMetal_Data)();
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_metal";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
@@ -139,25 +146,35 @@ bool ImGui_ImplMetal_Init(id<MTLDevice> device)
|
||||
bd->SharedMetalContext = [[MetalContext alloc] init];
|
||||
bd->SharedMetalContext.device = device;
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplMetal_InitPlatformInterface();
|
||||
ImGui_ImplMetal_InitMultiViewportSupport();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplMetal_Shutdown()
|
||||
{
|
||||
ImGui_ImplMetal_ShutdownPlatformInterface();
|
||||
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||
IM_UNUSED(bd);
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGui_ImplMetal_ShutdownMultiViewportSupport();
|
||||
ImGui_ImplMetal_DestroyDeviceObjects();
|
||||
ImGui_ImplMetal_DestroyBackendData();
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasViewports);
|
||||
}
|
||||
|
||||
void ImGui_ImplMetal_NewFrame(MTLRenderPassDescriptor* renderPassDescriptor)
|
||||
{
|
||||
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||
IM_ASSERT(bd->SharedMetalContext != nil && "No Metal context. Did you call ImGui_ImplMetal_Init() ?");
|
||||
IM_ASSERT(bd != nil && "Context or backend not initialized! Did you call ImGui_ImplMetal_Init()?");
|
||||
#ifdef IMGUI_IMPL_METAL_CPP
|
||||
bd->SharedMetalContext.framebufferDescriptor = [[[FramebufferDescriptor alloc] initWithRenderPassDescriptor:renderPassDescriptor]autorelease];
|
||||
#else
|
||||
bd->SharedMetalContext.framebufferDescriptor = [[FramebufferDescriptor alloc] initWithRenderPassDescriptor:renderPassDescriptor];
|
||||
|
||||
#endif
|
||||
if (bd->SharedMetalContext.depthStencilState == nil)
|
||||
ImGui_ImplMetal_CreateDeviceObjects(bd->SharedMetalContext.device);
|
||||
}
|
||||
@@ -246,14 +263,14 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id<MTLCommandBuffer> c
|
||||
size_t indexBufferOffset = 0;
|
||||
for (int n = 0; n < drawData->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = drawData->CmdLists[n];
|
||||
const ImDrawList* draw_list = drawData->CmdLists[n];
|
||||
|
||||
memcpy((char*)vertexBuffer.buffer.contents + vertexBufferOffset, cmd_list->VtxBuffer.Data, (size_t)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy((char*)indexBuffer.buffer.contents + indexBufferOffset, cmd_list->IdxBuffer.Data, (size_t)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
memcpy((char*)vertexBuffer.buffer.contents + vertexBufferOffset, draw_list->VtxBuffer.Data, (size_t)draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy((char*)indexBuffer.buffer.contents + indexBufferOffset, draw_list->IdxBuffer.Data, (size_t)draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
@@ -261,7 +278,7 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id<MTLCommandBuffer> c
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplMetal_SetupRenderState(drawData, commandBuffer, commandEncoder, renderPipelineState, vertexBuffer, vertexBufferOffset);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -291,7 +308,7 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id<MTLCommandBuffer> c
|
||||
|
||||
// Bind texture, Draw
|
||||
if (ImTextureID tex_id = pcmd->GetTexID())
|
||||
[commandEncoder setFragmentTexture:(__bridge id<MTLTexture>)(tex_id) atIndex:0];
|
||||
[commandEncoder setFragmentTexture:(__bridge id<MTLTexture>)(void*)(intptr_t)(tex_id) atIndex:0];
|
||||
|
||||
[commandEncoder setVertexBufferOffset:(vertexBufferOffset + pcmd->VtxOffset * sizeof(ImDrawVert)) atIndex:0];
|
||||
[commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle
|
||||
@@ -302,21 +319,18 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id<MTLCommandBuffer> c
|
||||
}
|
||||
}
|
||||
|
||||
vertexBufferOffset += (size_t)cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);
|
||||
indexBufferOffset += (size_t)cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx);
|
||||
vertexBufferOffset += (size_t)draw_list->VtxBuffer.Size * sizeof(ImDrawVert);
|
||||
indexBufferOffset += (size_t)draw_list->IdxBuffer.Size * sizeof(ImDrawIdx);
|
||||
}
|
||||
|
||||
__block MetalContext* sharedMetalContext = bd->SharedMetalContext;
|
||||
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer>)
|
||||
{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||
if (bd != nullptr)
|
||||
@synchronized(bd->SharedMetalContext.bufferCache)
|
||||
{
|
||||
@synchronized(bd->SharedMetalContext.bufferCache)
|
||||
{
|
||||
[bd->SharedMetalContext.bufferCache addObject:vertexBuffer];
|
||||
[bd->SharedMetalContext.bufferCache addObject:indexBuffer];
|
||||
}
|
||||
[sharedMetalContext.bufferCache addObject:vertexBuffer];
|
||||
[sharedMetalContext.bufferCache addObject:indexBuffer];
|
||||
}
|
||||
});
|
||||
}];
|
||||
@@ -347,7 +361,7 @@ bool ImGui_ImplMetal_CreateFontsTexture(id<MTLDevice> device)
|
||||
id <MTLTexture> texture = [device newTextureWithDescriptor:textureDescriptor];
|
||||
[texture replaceRegion:MTLRegionMake2D(0, 0, (NSUInteger)width, (NSUInteger)height) mipmapLevel:0 withBytes:pixels bytesPerRow:(NSUInteger)width * 4];
|
||||
bd->SharedMetalContext.fontTexture = texture;
|
||||
io.Fonts->SetTexID((__bridge void*)bd->SharedMetalContext.fontTexture); // ImTextureID == void*
|
||||
io.Fonts->SetTexID((ImTextureID)(intptr_t)(__bridge void*)bd->SharedMetalContext.fontTexture); // ImTextureID == ImU64
|
||||
|
||||
return (bd->SharedMetalContext.fontTexture != nil);
|
||||
}
|
||||
@@ -368,8 +382,10 @@ bool ImGui_ImplMetal_CreateDeviceObjects(id<MTLDevice> device)
|
||||
depthStencilDescriptor.depthCompareFunction = MTLCompareFunctionAlways;
|
||||
bd->SharedMetalContext.depthStencilState = [device newDepthStencilStateWithDescriptor:depthStencilDescriptor];
|
||||
ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows();
|
||||
#ifdef IMGUI_IMPL_METAL_CPP
|
||||
[depthStencilDescriptor release];
|
||||
#endif
|
||||
ImGui_ImplMetal_CreateFontsTexture(device);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -496,7 +512,7 @@ static void ImGui_ImplMetal_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
[commandBuffer commit];
|
||||
}
|
||||
|
||||
static void ImGui_ImplMetal_InitPlatformInterface()
|
||||
static void ImGui_ImplMetal_InitMultiViewportSupport()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Renderer_CreateWindow = ImGui_ImplMetal_CreateWindow;
|
||||
@@ -505,7 +521,7 @@ static void ImGui_ImplMetal_InitPlatformInterface()
|
||||
platform_io.Renderer_RenderWindow = ImGui_ImplMetal_RenderWindow;
|
||||
}
|
||||
|
||||
static void ImGui_ImplMetal_ShutdownPlatformInterface()
|
||||
static void ImGui_ImplMetal_ShutdownMultiViewportSupport()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
@@ -696,13 +712,13 @@ static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows()
|
||||
}
|
||||
|
||||
MTLVertexDescriptor* vertexDescriptor = [MTLVertexDescriptor vertexDescriptor];
|
||||
vertexDescriptor.attributes[0].offset = IM_OFFSETOF(ImDrawVert, pos);
|
||||
vertexDescriptor.attributes[0].offset = offsetof(ImDrawVert, pos);
|
||||
vertexDescriptor.attributes[0].format = MTLVertexFormatFloat2; // position
|
||||
vertexDescriptor.attributes[0].bufferIndex = 0;
|
||||
vertexDescriptor.attributes[1].offset = IM_OFFSETOF(ImDrawVert, uv);
|
||||
vertexDescriptor.attributes[1].offset = offsetof(ImDrawVert, uv);
|
||||
vertexDescriptor.attributes[1].format = MTLVertexFormatFloat2; // texCoords
|
||||
vertexDescriptor.attributes[1].bufferIndex = 0;
|
||||
vertexDescriptor.attributes[2].offset = IM_OFFSETOF(ImDrawVert, col);
|
||||
vertexDescriptor.attributes[2].offset = offsetof(ImDrawVert, col);
|
||||
vertexDescriptor.attributes[2].format = MTLVertexFormatUChar4; // color
|
||||
vertexDescriptor.attributes[2].bufferIndex = 0;
|
||||
vertexDescriptor.layouts[0].stepRate = 1;
|
||||
@@ -733,3 +749,7 @@ static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows()
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+50
-26
@@ -4,11 +4,16 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// Missing features or Issues:
|
||||
// [ ] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
|
||||
// **Prefer using the code in imgui_impl_opengl3.cpp**
|
||||
@@ -20,9 +25,11 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-10-07: OpenGL: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||
// 2024-06-28: OpenGL: ImGui_ImplOpenGL2_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL2_DestroyFontsTexture(). (#7748)
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-12-08: OpenGL: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
|
||||
// 2021-12-08: OpenGL: Fixed mishandling of the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86.
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-05-19: OpenGL: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
// 2021-01-03: OpenGL: Backup, setup and restore GL_SHADE_MODEL state, disable GL_STENCIL_TEST and disable GL_NORMAL_ARRAY client state to increase compatibility with legacy OpenGL applications.
|
||||
@@ -39,12 +46,9 @@
|
||||
// 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle.
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_opengl2.h"
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
|
||||
#include <stddef.h> // intptr_t
|
||||
#else
|
||||
#include <stdint.h> // intptr_t
|
||||
#endif
|
||||
|
||||
// Clang/GCC warnings with -Weverything
|
||||
#if defined(__clang__)
|
||||
@@ -67,6 +71,16 @@
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
// [Debugging]
|
||||
//#define IMGUI_IMPL_OPENGL_DEBUG
|
||||
#ifdef IMGUI_IMPL_OPENGL_DEBUG
|
||||
#include <stdio.h>
|
||||
#define GL_CALL(_CALL) do { _CALL; GLenum gl_err = glGetError(); if (gl_err != 0) fprintf(stderr, "GL error 0x%x returned from '%s'.\n", gl_err, #_CALL); } while (0) // Call with error check
|
||||
#else
|
||||
#define GL_CALL(_CALL) _CALL // Call without error check
|
||||
#endif
|
||||
|
||||
// OpenGL data
|
||||
struct ImGui_ImplOpenGL2_Data
|
||||
{
|
||||
GLuint FontTexture;
|
||||
@@ -82,13 +96,14 @@ static ImGui_ImplOpenGL2_Data* ImGui_ImplOpenGL2_GetBackendData()
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplOpenGL2_InitPlatformInterface();
|
||||
static void ImGui_ImplOpenGL2_ShutdownPlatformInterface();
|
||||
static void ImGui_ImplOpenGL2_InitMultiViewportSupport();
|
||||
static void ImGui_ImplOpenGL2_ShutdownMultiViewportSupport();
|
||||
|
||||
// Functions
|
||||
bool ImGui_ImplOpenGL2_Init()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
@@ -97,8 +112,7 @@ bool ImGui_ImplOpenGL2_Init()
|
||||
io.BackendRendererName = "imgui_impl_opengl2";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplOpenGL2_InitPlatformInterface();
|
||||
ImGui_ImplOpenGL2_InitMultiViewportSupport();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -109,20 +123,23 @@ void ImGui_ImplOpenGL2_Shutdown()
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplOpenGL2_ShutdownPlatformInterface();
|
||||
ImGui_ImplOpenGL2_ShutdownMultiViewportSupport();
|
||||
ImGui_ImplOpenGL2_DestroyDeviceObjects();
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasViewports;
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
void ImGui_ImplOpenGL2_NewFrame()
|
||||
{
|
||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplOpenGL2_Init()?");
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplOpenGL2_Init()?");
|
||||
|
||||
if (!bd->FontTexture)
|
||||
ImGui_ImplOpenGL2_CreateDeviceObjects();
|
||||
if (!bd->FontTexture)
|
||||
ImGui_ImplOpenGL2_CreateFontsTexture();
|
||||
}
|
||||
|
||||
static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height)
|
||||
@@ -159,7 +176,7 @@ static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_wid
|
||||
|
||||
// Setup viewport, orthographic projection matrix
|
||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||
glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height);
|
||||
GL_CALL(glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height));
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
@@ -199,16 +216,16 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data;
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, pos)));
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, uv)));
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + IM_OFFSETOF(ImDrawVert, col)));
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, pos)));
|
||||
glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, uv)));
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, col)));
|
||||
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
@@ -216,7 +233,7 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -270,6 +287,8 @@ bool ImGui_ImplOpenGL2_CreateFontsTexture()
|
||||
glBindTexture(GL_TEXTURE_2D, bd->FontTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
@@ -304,6 +323,7 @@ void ImGui_ImplOpenGL2_DestroyDeviceObjects()
|
||||
ImGui_ImplOpenGL2_DestroyFontsTexture();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
||||
@@ -321,17 +341,21 @@ static void ImGui_ImplOpenGL2_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
ImGui_ImplOpenGL2_RenderDrawData(viewport->DrawData);
|
||||
}
|
||||
|
||||
static void ImGui_ImplOpenGL2_InitPlatformInterface()
|
||||
static void ImGui_ImplOpenGL2_InitMultiViewportSupport()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL2_RenderWindow;
|
||||
}
|
||||
|
||||
static void ImGui_ImplOpenGL2_ShutdownPlatformInterface()
|
||||
static void ImGui_ImplOpenGL2_ShutdownMultiViewportSupport()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+12
-3
@@ -4,11 +4,16 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// Missing features or Issues:
|
||||
// [ ] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)**
|
||||
// **Prefer using the code in imgui_impl_opengl3.cpp**
|
||||
@@ -20,7 +25,9 @@
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_Init();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_NewFrame();
|
||||
@@ -31,3 +38,5 @@ IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyFontsTexture();
|
||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL2_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL2_DestroyDeviceObjects();
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+128
-67
@@ -5,17 +5,35 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices (Desktop OpenGL only).
|
||||
// [x] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset) [Desktop OpenGL only!]
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// About WebGL/ES:
|
||||
// - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES.
|
||||
// - This is done automatically on iOS, Android and Emscripten targets.
|
||||
// - For other targets, the define needs to be visible from the imgui_impl_opengl3.cpp compilation unit. If unsure, define globally or in imconfig.h.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-10-07: OpenGL: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||
// 2024-06-28: OpenGL: ImGui_ImplOpenGL3_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL3_DestroyFontsTexture(). (#7748)
|
||||
// 2024-05-07: OpenGL: Update loader for Linux to support EGL/GLVND. (#7562)
|
||||
// 2024-04-16: OpenGL: Detect ES3 contexts on desktop based on version string, to e.g. avoid calling glPolygonMode() on them. (#7447)
|
||||
// 2024-01-09: OpenGL: Update GL3W based imgui_impl_opengl3_loader.h to load "libGL.so" and variants, fixing regression on distros missing a symlink.
|
||||
// 2023-11-08: OpenGL: Update GL3W based imgui_impl_opengl3_loader.h to load "libGL.so" instead of "libGL.so.1", accommodating for NetBSD systems having only "libGL.so.3" available. (#6983)
|
||||
// 2023-10-05: OpenGL: Rename symbols in our internal loader so that LTO compilation with another copy of gl3w is possible. (#6875, #6668, #4445)
|
||||
// 2023-06-20: OpenGL: Fixed erroneous use glGetIntegerv(GL_CONTEXT_PROFILE_MASK) on contexts lower than 3.2. (#6539, #6333)
|
||||
// 2023-05-09: OpenGL: Support for glBindSampler() backup/restore on ES3. (#6375)
|
||||
// 2023-04-18: OpenGL: Restore front and back polygon mode separately when supported by context. (#6333)
|
||||
// 2023-03-23: OpenGL: Properly restoring "no shader program bound" if it was the case prior to running the rendering function. (#6267, #6220, #6224)
|
||||
// 2023-03-15: OpenGL: Fixed GL loader crash when GL_VERSION returns NULL. (#6154, #4445, #3530)
|
||||
// 2023-03-06: OpenGL: Fixed restoration of a potentially deleted OpenGL program, by calling glIsProgram(). (#6220, #6224)
|
||||
@@ -98,13 +116,10 @@
|
||||
#endif
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_opengl3.h"
|
||||
#include <stdio.h>
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
|
||||
#include <stddef.h> // intptr_t
|
||||
#else
|
||||
#include <stdint.h> // intptr_t
|
||||
#endif
|
||||
#if defined(__APPLE__)
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
@@ -112,6 +127,7 @@
|
||||
// Clang/GCC warnings with -Weverything
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: ignore unknown flags
|
||||
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast
|
||||
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||
#pragma clang diagnostic ignored "-Wunused-macros" // warning: macro is not used
|
||||
@@ -123,6 +139,7 @@
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx'
|
||||
#pragma GCC diagnostic ignored "-Wcast-function-type" // warning: cast between incompatible function types (for loader)
|
||||
#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when simplifying division / ..when changing X +- C1 cmp C2 to X cmp C2 -+ C1
|
||||
#endif
|
||||
|
||||
// GL includes
|
||||
@@ -150,6 +167,7 @@
|
||||
// In the rest of your app/engine, you can use another loader of your choice (gl3w, glew, glad, glbinding, glext, glLoadGen, etc.).
|
||||
// If you happen to be developing a new feature for this backend (imgui_impl_opengl3.cpp):
|
||||
// - You may need to regenerate imgui_impl_opengl3_loader.h to add new symbols. See https://github.com/dearimgui/gl3w_stripped
|
||||
// Typically you would run: python3 ./gl3w_gen.py --output ../imgui/backends/imgui_impl_opengl3_loader.h --ref ../imgui/backends/imgui_impl_opengl3.cpp ./extra_symbols.txt
|
||||
// - You can temporarily use an unstripped version. See https://github.com/dearimgui/gl3w_stripped/releases
|
||||
// Changes to this backend using new APIs should be accompanied by a regenerated stripped loader version.
|
||||
#define IMGL3W_IMPL
|
||||
@@ -167,19 +185,16 @@
|
||||
#define GL_VERTEX_ARRAY_BINDING GL_VERTEX_ARRAY_BINDING_OES
|
||||
#endif
|
||||
|
||||
// Desktop GL 2.0+ has glPolygonMode() which GL ES and WebGL don't have.
|
||||
#ifdef GL_POLYGON_MODE
|
||||
#define IMGUI_IMPL_HAS_POLYGON_MODE
|
||||
// Desktop GL 2.0+ has extension and glPolygonMode() which GL ES and WebGL don't have..
|
||||
// A desktop ES context can technically compile fine with our loader, so we also perform a runtime checks
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3)
|
||||
#define IMGUI_IMPL_OPENGL_HAS_EXTENSIONS // has glGetIntegerv(GL_NUM_EXTENSIONS)
|
||||
#define IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE // may have glPolygonMode()
|
||||
#endif
|
||||
|
||||
// Desktop GL 3.2+ has glDrawElementsBaseVertex() which GL ES and WebGL don't have.
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && defined(GL_VERSION_3_2)
|
||||
#define IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
|
||||
#endif
|
||||
|
||||
// Desktop GL 3.3+ has glBindSampler()
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && defined(GL_VERSION_3_3)
|
||||
#define IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||
// Desktop GL 2.1+ and GL ES 3.0+ have glBindBuffer() with GL_PIXEL_UNPACK_BUFFER target.
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2)
|
||||
#define IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_BUFFER_PIXEL_UNPACK
|
||||
#endif
|
||||
|
||||
// Desktop GL 3.1+ has GL_PRIMITIVE_RESTART state
|
||||
@@ -187,9 +202,14 @@
|
||||
#define IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
|
||||
#endif
|
||||
|
||||
// Desktop GL use extension detection
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3)
|
||||
#define IMGUI_IMPL_OPENGL_MAY_HAVE_EXTENSIONS
|
||||
// Desktop GL 3.2+ has glDrawElementsBaseVertex() which GL ES and WebGL don't have.
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && defined(GL_VERSION_3_2)
|
||||
#define IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
|
||||
#endif
|
||||
|
||||
// Desktop GL 3.3+ and GL ES 3.0+ have glBindSampler()
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2) && (defined(IMGUI_IMPL_OPENGL_ES3) || defined(GL_VERSION_3_3))
|
||||
#define IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||
#endif
|
||||
|
||||
// [Debugging]
|
||||
@@ -206,6 +226,10 @@ struct ImGui_ImplOpenGL3_Data
|
||||
{
|
||||
GLuint GlVersion; // Extracted at runtime using GL_MAJOR_VERSION, GL_MINOR_VERSION queries (e.g. 320 for GL 3.2)
|
||||
char GlslVersionString[32]; // Specified by user or detected based on compile time GL settings.
|
||||
bool GlProfileIsES2;
|
||||
bool GlProfileIsES3;
|
||||
bool GlProfileIsCompat;
|
||||
GLint GlProfileMask;
|
||||
GLuint FontTexture;
|
||||
GLuint ShaderHandle;
|
||||
GLint AttribLocationTex; // Uniforms location
|
||||
@@ -216,6 +240,7 @@ struct ImGui_ImplOpenGL3_Data
|
||||
unsigned int VboHandle, ElementsHandle;
|
||||
GLsizeiptr VertexBufferSize;
|
||||
GLsizeiptr IndexBufferSize;
|
||||
bool HasPolygonMode;
|
||||
bool HasClipOrigin;
|
||||
bool UseBufferSubData;
|
||||
|
||||
@@ -230,8 +255,8 @@ static ImGui_ImplOpenGL3_Data* ImGui_ImplOpenGL3_GetBackendData()
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplOpenGL3_InitPlatformInterface();
|
||||
static void ImGui_ImplOpenGL3_ShutdownPlatformInterface();
|
||||
static void ImGui_ImplOpenGL3_InitMultiViewportSupport();
|
||||
static void ImGui_ImplOpenGL3_ShutdownMultiViewportSupport();
|
||||
|
||||
// OpenGL vertex attribute state (for ES 1.0 and ES 2.0 only)
|
||||
#ifndef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
@@ -261,6 +286,7 @@ struct ImGui_ImplOpenGL3_VtxAttribState
|
||||
bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
// Initialize our loader
|
||||
@@ -278,18 +304,32 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
io.BackendRendererName = "imgui_impl_opengl3";
|
||||
|
||||
// Query for GL version (e.g. 320 for GL 3.2)
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2)
|
||||
const char* gl_version_str = (const char*)glGetString(GL_VERSION);
|
||||
#if defined(IMGUI_IMPL_OPENGL_ES2)
|
||||
// GLES 2
|
||||
bd->GlVersion = 200;
|
||||
bd->GlProfileIsES2 = true;
|
||||
#else
|
||||
// Desktop or GLES 3
|
||||
GLint major = 0;
|
||||
GLint minor = 0;
|
||||
glGetIntegerv(GL_MAJOR_VERSION, &major);
|
||||
glGetIntegerv(GL_MINOR_VERSION, &minor);
|
||||
if (major == 0 && minor == 0)
|
||||
{
|
||||
// Query GL_VERSION in desktop GL 2.x, the string will start with "<major>.<minor>"
|
||||
const char* gl_version = (const char*)glGetString(GL_VERSION);
|
||||
sscanf(gl_version, "%d.%d", &major, &minor);
|
||||
}
|
||||
sscanf(gl_version_str, "%d.%d", &major, &minor); // Query GL_VERSION in desktop GL 2.x, the string will start with "<major>.<minor>"
|
||||
bd->GlVersion = (GLuint)(major * 100 + minor * 10);
|
||||
#if defined(GL_CONTEXT_PROFILE_MASK)
|
||||
if (bd->GlVersion >= 320)
|
||||
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &bd->GlProfileMask);
|
||||
bd->GlProfileIsCompat = (bd->GlProfileMask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0;
|
||||
#endif
|
||||
|
||||
#if defined(IMGUI_IMPL_OPENGL_ES3)
|
||||
bd->GlProfileIsES3 = true;
|
||||
#else
|
||||
if (strncmp(gl_version_str, "OpenGL ES 3", 11) == 0)
|
||||
bd->GlProfileIsES3 = true;
|
||||
#endif
|
||||
|
||||
bd->UseBufferSubData = false;
|
||||
/*
|
||||
@@ -300,12 +340,10 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
bd->UseBufferSubData = true;
|
||||
#endif
|
||||
*/
|
||||
#else
|
||||
bd->GlVersion = 200; // GLES 2
|
||||
#endif
|
||||
|
||||
#ifdef IMGUI_IMPL_OPENGL_DEBUG
|
||||
printf("GL_MAJOR_VERSION = %d\nGL_MINOR_VERSION = %d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", major, minor, (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG]
|
||||
printf("GlVersion = %d, \"%s\"\nGlProfileIsCompat = %d\nGlProfileMask = 0x%X\nGlProfileIsES2/IsEs3 = %d/%d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", bd->GlVersion, gl_version_str, bd->GlProfileIsCompat, bd->GlProfileMask, bd->GlProfileIsES2, bd->GlProfileIsES3, (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG]
|
||||
#endif
|
||||
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
|
||||
@@ -338,8 +376,11 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture);
|
||||
|
||||
// Detect extensions we support
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE
|
||||
bd->HasPolygonMode = (!bd->GlProfileIsES2 && !bd->GlProfileIsES3);
|
||||
#endif
|
||||
bd->HasClipOrigin = (bd->GlVersion >= 450);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_EXTENSIONS
|
||||
#ifdef IMGUI_IMPL_OPENGL_HAS_EXTENSIONS
|
||||
GLint num_extensions = 0;
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
|
||||
for (GLint i = 0; i < num_extensions; i++)
|
||||
@@ -350,8 +391,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplOpenGL3_InitPlatformInterface();
|
||||
ImGui_ImplOpenGL3_InitMultiViewportSupport();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -362,20 +402,23 @@ void ImGui_ImplOpenGL3_Shutdown()
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplOpenGL3_ShutdownPlatformInterface();
|
||||
ImGui_ImplOpenGL3_ShutdownMultiViewportSupport();
|
||||
ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasViewports);
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
void ImGui_ImplOpenGL3_NewFrame()
|
||||
{
|
||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplOpenGL3_Init()?");
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplOpenGL3_Init()?");
|
||||
|
||||
if (!bd->ShaderHandle)
|
||||
ImGui_ImplOpenGL3_CreateDeviceObjects();
|
||||
if (!bd->FontTexture)
|
||||
ImGui_ImplOpenGL3_CreateFontsTexture();
|
||||
}
|
||||
|
||||
static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_width, int fb_height, GLuint vertex_array_object)
|
||||
@@ -394,8 +437,9 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
|
||||
if (bd->GlVersion >= 310)
|
||||
glDisable(GL_PRIMITIVE_RESTART);
|
||||
#endif
|
||||
#ifdef IMGUI_IMPL_HAS_POLYGON_MODE
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE
|
||||
if (bd->HasPolygonMode)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
#endif
|
||||
|
||||
// Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT)
|
||||
@@ -431,8 +475,8 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
|
||||
glUniformMatrix4fv(bd->AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
|
||||
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||
if (bd->GlVersion >= 330)
|
||||
glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise.
|
||||
if (bd->GlVersion >= 330 || bd->GlProfileIsES3)
|
||||
glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 and GL ES 3.0 may set that otherwise.
|
||||
#endif
|
||||
|
||||
(void)vertex_array_object;
|
||||
@@ -446,9 +490,9 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
|
||||
GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxPos));
|
||||
GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxUV));
|
||||
GL_CALL(glEnableVertexAttribArray(bd->AttribLocationVtxColor));
|
||||
GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)));
|
||||
GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)));
|
||||
GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)));
|
||||
GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, pos)));
|
||||
GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, uv)));
|
||||
GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, col)));
|
||||
}
|
||||
|
||||
// OpenGL3 Render function.
|
||||
@@ -470,7 +514,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
GLuint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&last_program);
|
||||
GLuint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)&last_texture);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||
GLuint last_sampler; if (bd->GlVersion >= 330) { glGetIntegerv(GL_SAMPLER_BINDING, (GLint*)&last_sampler); } else { last_sampler = 0; }
|
||||
GLuint last_sampler; if (bd->GlVersion >= 330 || bd->GlProfileIsES3) { glGetIntegerv(GL_SAMPLER_BINDING, (GLint*)&last_sampler); } else { last_sampler = 0; }
|
||||
#endif
|
||||
GLuint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&last_array_buffer);
|
||||
#ifndef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
@@ -483,8 +527,8 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
GLuint last_vertex_array_object; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, (GLint*)&last_vertex_array_object);
|
||||
#endif
|
||||
#ifdef IMGUI_IMPL_HAS_POLYGON_MODE
|
||||
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE
|
||||
GLint last_polygon_mode[2]; if (bd->HasPolygonMode) { glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); }
|
||||
#endif
|
||||
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
|
||||
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
|
||||
@@ -519,7 +563,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
|
||||
// Upload vertex/index buffers
|
||||
// - OpenGL drivers are in a very sorry state nowadays....
|
||||
@@ -529,8 +573,8 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
// - We are now back to using exclusively glBufferData(). So bd->UseBufferSubData IS ALWAYS FALSE in this code.
|
||||
// We are keeping the old code path for a while in case people finding new issues may want to test the bd->UseBufferSubData path.
|
||||
// - See https://github.com/ocornut/imgui/issues/4468 and please report any corruption issues.
|
||||
const GLsizeiptr vtx_buffer_size = (GLsizeiptr)cmd_list->VtxBuffer.Size * (int)sizeof(ImDrawVert);
|
||||
const GLsizeiptr idx_buffer_size = (GLsizeiptr)cmd_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx);
|
||||
const GLsizeiptr vtx_buffer_size = (GLsizeiptr)draw_list->VtxBuffer.Size * (int)sizeof(ImDrawVert);
|
||||
const GLsizeiptr idx_buffer_size = (GLsizeiptr)draw_list->IdxBuffer.Size * (int)sizeof(ImDrawIdx);
|
||||
if (bd->UseBufferSubData)
|
||||
{
|
||||
if (bd->VertexBufferSize < vtx_buffer_size)
|
||||
@@ -543,18 +587,18 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
bd->IndexBufferSize = idx_buffer_size;
|
||||
GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, bd->IndexBufferSize, nullptr, GL_STREAM_DRAW));
|
||||
}
|
||||
GL_CALL(glBufferSubData(GL_ARRAY_BUFFER, 0, vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer.Data));
|
||||
GL_CALL(glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer.Data));
|
||||
GL_CALL(glBufferSubData(GL_ARRAY_BUFFER, 0, vtx_buffer_size, (const GLvoid*)draw_list->VtxBuffer.Data));
|
||||
GL_CALL(glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, idx_buffer_size, (const GLvoid*)draw_list->IdxBuffer.Data));
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_CALL(glBufferData(GL_ARRAY_BUFFER, vtx_buffer_size, (const GLvoid*)cmd_list->VtxBuffer.Data, GL_STREAM_DRAW));
|
||||
GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size, (const GLvoid*)cmd_list->IdxBuffer.Data, GL_STREAM_DRAW));
|
||||
GL_CALL(glBufferData(GL_ARRAY_BUFFER, vtx_buffer_size, (const GLvoid*)draw_list->VtxBuffer.Data, GL_STREAM_DRAW));
|
||||
GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_buffer_size, (const GLvoid*)draw_list->IdxBuffer.Data, GL_STREAM_DRAW));
|
||||
}
|
||||
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
@@ -562,7 +606,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -597,7 +641,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
if (last_program == 0 || glIsProgram(last_program)) glUseProgram(last_program);
|
||||
glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||
if (bd->GlVersion >= 330)
|
||||
if (bd->GlVersion >= 330 || bd->GlProfileIsES3)
|
||||
glBindSampler(0, last_sampler);
|
||||
#endif
|
||||
glActiveTexture(last_active_texture);
|
||||
@@ -622,9 +666,11 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
if (bd->GlVersion >= 310) { if (last_enable_primitive_restart) glEnable(GL_PRIMITIVE_RESTART); else glDisable(GL_PRIMITIVE_RESTART); }
|
||||
#endif
|
||||
|
||||
#ifdef IMGUI_IMPL_HAS_POLYGON_MODE
|
||||
glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]);
|
||||
#endif
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE
|
||||
// Desktop OpenGL 3.0 and OpenGL 3.1 had separate polygon draw modes for front-facing and back-facing faces of polygons
|
||||
if (bd->HasPolygonMode) { if (bd->GlVersion <= 310 || bd->GlProfileIsCompat) { glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]); } else { glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]); } }
|
||||
#endif // IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE
|
||||
|
||||
glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
|
||||
glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
|
||||
(void)bd; // Not all compilation paths use this
|
||||
@@ -648,12 +694,14 @@ bool ImGui_ImplOpenGL3_CreateFontsTexture()
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_2D, bd->FontTexture));
|
||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
|
||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
#ifdef GL_UNPACK_ROW_LENGTH // Not on WebGL/ES
|
||||
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
|
||||
#endif
|
||||
GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
|
||||
|
||||
// Store our identifier
|
||||
// Store identifier
|
||||
io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture);
|
||||
|
||||
// Restore state
|
||||
@@ -720,6 +768,10 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects()
|
||||
GLint last_texture, last_array_buffer;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
|
||||
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_BUFFER_PIXEL_UNPACK
|
||||
GLint last_pixel_unpack_buffer = 0;
|
||||
if (bd->GlVersion >= 210) { glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING, &last_pixel_unpack_buffer); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); }
|
||||
#endif
|
||||
#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
GLint last_vertex_array;
|
||||
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
|
||||
@@ -855,13 +907,15 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects()
|
||||
|
||||
// Create shaders
|
||||
const GLchar* vertex_shader_with_version[2] = { bd->GlslVersionString, vertex_shader };
|
||||
GLuint vert_handle = glCreateShader(GL_VERTEX_SHADER);
|
||||
GLuint vert_handle;
|
||||
GL_CALL(vert_handle = glCreateShader(GL_VERTEX_SHADER));
|
||||
glShaderSource(vert_handle, 2, vertex_shader_with_version, nullptr);
|
||||
glCompileShader(vert_handle);
|
||||
CheckShader(vert_handle, "vertex shader");
|
||||
|
||||
const GLchar* fragment_shader_with_version[2] = { bd->GlslVersionString, fragment_shader };
|
||||
GLuint frag_handle = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
GLuint frag_handle;
|
||||
GL_CALL(frag_handle = glCreateShader(GL_FRAGMENT_SHADER));
|
||||
glShaderSource(frag_handle, 2, fragment_shader_with_version, nullptr);
|
||||
glCompileShader(frag_handle);
|
||||
CheckShader(frag_handle, "fragment shader");
|
||||
@@ -893,6 +947,9 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects()
|
||||
// Restore modified GL state
|
||||
glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_BUFFER_PIXEL_UNPACK
|
||||
if (bd->GlVersion >= 210) { glBindBuffer(GL_PIXEL_UNPACK_BUFFER, last_pixel_unpack_buffer); }
|
||||
#endif
|
||||
#ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
glBindVertexArray(last_vertex_array);
|
||||
#endif
|
||||
@@ -926,20 +983,24 @@ static void ImGui_ImplOpenGL3_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
ImGui_ImplOpenGL3_RenderDrawData(viewport->DrawData);
|
||||
}
|
||||
|
||||
static void ImGui_ImplOpenGL3_InitPlatformInterface()
|
||||
static void ImGui_ImplOpenGL3_InitMultiViewportSupport()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL3_RenderWindow;
|
||||
}
|
||||
|
||||
static void ImGui_ImplOpenGL3_ShutdownPlatformInterface()
|
||||
static void ImGui_ImplOpenGL3_ShutdownMultiViewportSupport()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+18
-7
@@ -5,13 +5,21 @@
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices (Desktop OpenGL only).
|
||||
// [x] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset) [Desktop OpenGL only!]
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// About WebGL/ES:
|
||||
// - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES.
|
||||
// - This is done automatically on iOS, Android and Emscripten targets.
|
||||
// - For other targets, the define needs to be visible from the imgui_impl_opengl3.cpp compilation unit. If unsure, define globally or in imconfig.h.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// About GLSL version:
|
||||
// The 'glsl_version' initialization parameter should be nullptr (default) or a "#version XXX" string.
|
||||
@@ -20,8 +28,9 @@
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
// Backend API
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = nullptr);
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame();
|
||||
@@ -33,9 +42,9 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture();
|
||||
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
||||
|
||||
// Specific OpenGL ES versions
|
||||
//#define IMGUI_IMPL_OPENGL_ES2 // Auto-detected on Emscripten
|
||||
//#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android
|
||||
// Configuration flags to add in your imconfig file:
|
||||
//#define IMGUI_IMPL_OPENGL_ES2 // Enable ES 2 (Auto-detected on Emscripten)
|
||||
//#define IMGUI_IMPL_OPENGL_ES3 // Enable ES 3 (Auto-detected on iOS/Android)
|
||||
|
||||
// You can explicitly select GLES2 or GLES3 API by using one of the '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line.
|
||||
#if !defined(IMGUI_IMPL_OPENGL_ES2) \
|
||||
@@ -54,3 +63,5 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+130
-19
@@ -10,7 +10,7 @@
|
||||
// THE REST OF YOUR APP SHOULD USE A DIFFERENT GL LOADER: ANY GL LOADER OF YOUR CHOICE.
|
||||
//
|
||||
// IF YOU GET BUILD ERRORS IN THIS FILE (commonly macro redefinitions or function redefinitions):
|
||||
// IT LIKELY MEANS THAT YOU ARE BUILDING 'imgui_impl_opengl3.cpp' OR INCUDING 'imgui_impl_opengl3_loader.h'
|
||||
// IT LIKELY MEANS THAT YOU ARE BUILDING 'imgui_impl_opengl3.cpp' OR INCLUDING 'imgui_impl_opengl3_loader.h'
|
||||
// IN THE SAME COMPILATION UNIT AS ONE OF YOUR FILE WHICH IS USING A THIRD-PARTY OPENGL LOADER.
|
||||
// (e.g. COULD HAPPEN IF YOU ARE DOING A UNITY/JUMBO BUILD, OR INCLUDING .CPP FILES FROM OTHERS)
|
||||
// YOU SHOULD NOT BUILD BOTH IN THE SAME COMPILATION UNIT.
|
||||
@@ -18,7 +18,7 @@
|
||||
// WILL NOT BE USING OUR LOADER, AND INSTEAD EXPECT ANOTHER/YOUR LOADER TO BE AVAILABLE IN THE COMPILATION UNIT.
|
||||
//
|
||||
// Regenerate with:
|
||||
// python gl3w_gen.py --output ../imgui/backends/imgui_impl_opengl3_loader.h --ref ../imgui/backends/imgui_impl_opengl3.cpp ./extra_symbols.txt
|
||||
// python3 gl3w_gen.py --output ../imgui/backends/imgui_impl_opengl3_loader.h --ref ../imgui/backends/imgui_impl_opengl3.cpp ./extra_symbols.txt
|
||||
//
|
||||
// More info:
|
||||
// https://github.com/dearimgui/gl3w_stripped
|
||||
@@ -118,7 +118,7 @@ extern "C" {
|
||||
** included as <GL/glcorearb.h>.
|
||||
**
|
||||
** glcorearb.h includes only APIs in the latest OpenGL core profile
|
||||
** implementation together with APIs in newer ARB extensions which
|
||||
** implementation together with APIs in newer ARB extensions which
|
||||
** can be supported by the core profile. It does not, and never will
|
||||
** include functionality removed from the core profile, such as
|
||||
** fixed-function vertex and fragment processing.
|
||||
@@ -154,6 +154,8 @@ typedef khronos_uint8_t GLubyte;
|
||||
#define GL_ONE 1
|
||||
#define GL_SRC_ALPHA 0x0302
|
||||
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
|
||||
#define GL_FRONT 0x0404
|
||||
#define GL_BACK 0x0405
|
||||
#define GL_FRONT_AND_BACK 0x0408
|
||||
#define GL_POLYGON_MODE 0x0B40
|
||||
#define GL_CULL_FACE 0x0B44
|
||||
@@ -179,6 +181,9 @@ typedef khronos_uint8_t GLubyte;
|
||||
#define GL_LINEAR 0x2601
|
||||
#define GL_TEXTURE_MAG_FILTER 0x2800
|
||||
#define GL_TEXTURE_MIN_FILTER 0x2801
|
||||
#define GL_TEXTURE_WRAP_S 0x2802
|
||||
#define GL_TEXTURE_WRAP_T 0x2803
|
||||
#define GL_REPEAT 0x2901
|
||||
typedef void (APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode);
|
||||
typedef void (APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
|
||||
@@ -229,6 +234,9 @@ GLAPI void APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);
|
||||
GLAPI void APIENTRY glGenTextures (GLsizei n, GLuint *textures);
|
||||
#endif
|
||||
#endif /* GL_VERSION_1_1 */
|
||||
#ifndef GL_VERSION_1_2
|
||||
#define GL_CLAMP_TO_EDGE 0x812F
|
||||
#endif /* GL_VERSION_1_2 */
|
||||
#ifndef GL_VERSION_1_3
|
||||
#define GL_TEXTURE0 0x84C0
|
||||
#define GL_ACTIVE_TEXTURE 0x84E0
|
||||
@@ -344,6 +352,10 @@ GLAPI void APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean
|
||||
GLAPI void APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
|
||||
#endif
|
||||
#endif /* GL_VERSION_2_0 */
|
||||
#ifndef GL_VERSION_2_1
|
||||
#define GL_PIXEL_UNPACK_BUFFER 0x88EC
|
||||
#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
|
||||
#endif /* GL_VERSION_2_1 */
|
||||
#ifndef GL_VERSION_3_0
|
||||
typedef khronos_uint16_t GLhalf;
|
||||
#define GL_MAJOR_VERSION 0x821B
|
||||
@@ -373,6 +385,8 @@ GLAPI void APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays);
|
||||
typedef struct __GLsync *GLsync;
|
||||
typedef khronos_uint64_t GLuint64;
|
||||
typedef khronos_int64_t GLint64;
|
||||
#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
|
||||
#define GL_CONTEXT_PROFILE_MASK 0x9126
|
||||
typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
|
||||
typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
@@ -463,7 +477,7 @@ GL3W_API int imgl3wIsSupported(int major, int minor);
|
||||
GL3W_API GL3WglProc imgl3wGetProcAddress(const char *proc);
|
||||
|
||||
/* gl3w internal state */
|
||||
union GL3WProcs {
|
||||
union ImGL3WProcs {
|
||||
GL3WglProc ptr[59];
|
||||
struct {
|
||||
PFNGLACTIVETEXTUREPROC ActiveTexture;
|
||||
@@ -528,7 +542,7 @@ union GL3WProcs {
|
||||
} gl;
|
||||
};
|
||||
|
||||
GL3W_API extern union GL3WProcs imgl3wProcs;
|
||||
GL3W_API extern union ImGL3WProcs imgl3wProcs;
|
||||
|
||||
/* OpenGL functions */
|
||||
#define glActiveTexture imgl3wProcs.gl.ActiveTexture
|
||||
@@ -604,7 +618,7 @@ extern "C" {
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#define GL3W_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
||||
#if defined(_WIN32)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
@@ -657,26 +671,123 @@ static GL3WglProc get_proc(const char *proc)
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
|
||||
static void *libgl;
|
||||
static GL3WglProc (*glx_get_proc_address)(const GLubyte *);
|
||||
static void* libgl; // OpenGL library
|
||||
static void* libglx; // GLX library
|
||||
static void* libegl; // EGL library
|
||||
static GL3WGetProcAddressProc gl_get_proc_address;
|
||||
|
||||
static void close_libgl(void)
|
||||
{
|
||||
if (libgl) {
|
||||
dlclose(libgl);
|
||||
libgl = NULL;
|
||||
}
|
||||
if (libegl) {
|
||||
dlclose(libegl);
|
||||
libegl = NULL;
|
||||
}
|
||||
if (libglx) {
|
||||
dlclose(libglx);
|
||||
libglx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int is_library_loaded(const char* name, void** lib)
|
||||
{
|
||||
*lib = dlopen(name, RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
|
||||
return *lib != NULL;
|
||||
}
|
||||
|
||||
static int open_libs(void)
|
||||
{
|
||||
// On Linux we have two APIs to get process addresses: EGL and GLX.
|
||||
// EGL is supported under both X11 and Wayland, whereas GLX is X11-specific.
|
||||
|
||||
libgl = NULL;
|
||||
libegl = NULL;
|
||||
libglx = NULL;
|
||||
|
||||
// First check what's already loaded, the windowing library might have
|
||||
// already loaded either EGL or GLX and we want to use the same one.
|
||||
|
||||
if (is_library_loaded("libEGL.so.1", &libegl) ||
|
||||
is_library_loaded("libGLX.so.0", &libglx)) {
|
||||
libgl = dlopen("libOpenGL.so.0", RTLD_LAZY | RTLD_LOCAL);
|
||||
if (libgl)
|
||||
return GL3W_OK;
|
||||
else
|
||||
close_libgl();
|
||||
}
|
||||
|
||||
if (is_library_loaded("libGL.so", &libgl))
|
||||
return GL3W_OK;
|
||||
if (is_library_loaded("libGL.so.1", &libgl))
|
||||
return GL3W_OK;
|
||||
if (is_library_loaded("libGL.so.3", &libgl))
|
||||
return GL3W_OK;
|
||||
|
||||
// Neither is already loaded, so we have to load one. Try EGL first
|
||||
// because it is supported under both X11 and Wayland.
|
||||
|
||||
// Load OpenGL + EGL
|
||||
libgl = dlopen("libOpenGL.so.0", RTLD_LAZY | RTLD_LOCAL);
|
||||
libegl = dlopen("libEGL.so.1", RTLD_LAZY | RTLD_LOCAL);
|
||||
if (libgl && libegl)
|
||||
return GL3W_OK;
|
||||
else
|
||||
close_libgl();
|
||||
|
||||
// Fall back to legacy libGL, which includes GLX
|
||||
// While most systems use libGL.so.1, NetBSD seems to use that libGL.so.3. See https://github.com/ocornut/imgui/issues/6983
|
||||
libgl = dlopen("libGL.so", RTLD_LAZY | RTLD_LOCAL);
|
||||
if (!libgl)
|
||||
libgl = dlopen("libGL.so.1", RTLD_LAZY | RTLD_LOCAL);
|
||||
if (!libgl)
|
||||
libgl = dlopen("libGL.so.3", RTLD_LAZY | RTLD_LOCAL);
|
||||
|
||||
if (libgl)
|
||||
return GL3W_OK;
|
||||
|
||||
return GL3W_ERROR_LIBRARY_OPEN;
|
||||
}
|
||||
|
||||
static int open_libgl(void)
|
||||
{
|
||||
libgl = dlopen("libGL.so.1", RTLD_LAZY | RTLD_LOCAL);
|
||||
if (!libgl)
|
||||
int res = open_libs();
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
if (libegl)
|
||||
*(void**)(&gl_get_proc_address) = dlsym(libegl, "eglGetProcAddress");
|
||||
else if (libglx)
|
||||
*(void**)(&gl_get_proc_address) = dlsym(libglx, "glXGetProcAddressARB");
|
||||
else
|
||||
*(void**)(&gl_get_proc_address) = dlsym(libgl, "glXGetProcAddressARB");
|
||||
|
||||
if (!gl_get_proc_address) {
|
||||
close_libgl();
|
||||
return GL3W_ERROR_LIBRARY_OPEN;
|
||||
*(void **)(&glx_get_proc_address) = dlsym(libgl, "glXGetProcAddressARB");
|
||||
}
|
||||
|
||||
return GL3W_OK;
|
||||
}
|
||||
|
||||
static void close_libgl(void) { dlclose(libgl); }
|
||||
|
||||
static GL3WglProc get_proc(const char *proc)
|
||||
static GL3WglProc get_proc(const char* proc)
|
||||
{
|
||||
GL3WglProc res;
|
||||
res = glx_get_proc_address((const GLubyte *)proc);
|
||||
GL3WglProc res = NULL;
|
||||
|
||||
// Before EGL version 1.5, eglGetProcAddress doesn't support querying core
|
||||
// functions and may return a dummy function if we try, so try to load the
|
||||
// function from the GL library directly first.
|
||||
if (libegl)
|
||||
*(void**)(&res) = dlsym(libgl, proc);
|
||||
|
||||
if (!res)
|
||||
*(void **)(&res) = dlsym(libgl, proc);
|
||||
res = gl_get_proc_address(proc);
|
||||
|
||||
if (!libegl && !res)
|
||||
*(void**)(&res) = dlsym(libgl, proc);
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
@@ -790,12 +901,12 @@ static const char *proc_names[] = {
|
||||
"glViewport",
|
||||
};
|
||||
|
||||
GL3W_API union GL3WProcs imgl3wProcs;
|
||||
GL3W_API union ImGL3WProcs imgl3wProcs;
|
||||
|
||||
static void load_procs(GL3WGetProcAddressProc proc)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < ARRAY_SIZE(proc_names); i++)
|
||||
for (i = 0; i < GL3W_ARRAY_SIZE(proc_names); i++)
|
||||
imgl3wProcs.ptr[i] = proc(proc_names[i]);
|
||||
}
|
||||
|
||||
|
||||
+17
-6
@@ -4,26 +4,34 @@
|
||||
// - Requires linking with the GameController framework ("-framework GameController").
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Clipboard support is part of core Dear ImGui (no specific code in this backend).
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/Pen.
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy kVK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend).
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy kVK_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: IME support.
|
||||
// [X] Platform: Multi-viewport / platform windows.
|
||||
// [x] Platform: Multi-viewport / platform windows.
|
||||
// Issues:
|
||||
// [ ] Platform: Multi-viewport: Window size not correctly reported when enabling io.ConfigViewportsNoDecoration
|
||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
#ifdef __OBJC__
|
||||
|
||||
@class NSEvent;
|
||||
@class NSView;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplOSX_Init(NSView* _Nonnull view);
|
||||
IMGUI_IMPL_API void ImGui_ImplOSX_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(NSView* _Nullable view);
|
||||
@@ -38,9 +46,12 @@ IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(NSView* _Nullable view);
|
||||
// #include <AppKit/AppKit.hpp>
|
||||
#ifndef __OBJC__
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplOSX_Init(void* _Nonnull view);
|
||||
IMGUI_IMPL_API void ImGui_ImplOSX_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(void* _Nullable view);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+115
-52
@@ -4,20 +4,27 @@
|
||||
// - Requires linking with the GameController framework ("-framework GameController").
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Clipboard support is part of core Dear ImGui (no specific code in this backend).
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/Pen.
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy kVK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: OSX clipboard is supported within core Dear ImGui (no specific code in this backend).
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy kVK_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: IME support.
|
||||
// [X] Platform: Multi-viewport / platform windows.
|
||||
// [x] Platform: Multi-viewport / platform windows.
|
||||
// Issues:
|
||||
// [ ] Platform: Multi-viewport: Window size not correctly reported when enabling io.ConfigViewportsNoDecoration
|
||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#import "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#import "imgui_impl_osx.h"
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <Carbon/Carbon.h>
|
||||
@@ -26,7 +33,14 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-XX-XX: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-01-20: Removed notification observer when shutting down. (#8331)
|
||||
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
||||
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
|
||||
// - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn
|
||||
// - io.PlatformSetImeDataFn -> platform_io.Platform_SetImeDataFn
|
||||
// 2024-07-02: Update for io.SetPlatformImeDataFn() -> io.PlatformSetImeDataFn() renaming in main library.
|
||||
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F20 function keys. Stopped mapping F13 into PrintScreen.
|
||||
// 2023-04-09: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_Pen.
|
||||
// 2023-02-01: Fixed scroll wheel scaling for devices emitting events with hasPreciseScrollingDeltas==false (e.g. non-Apple mices).
|
||||
// 2022-11-02: Fixed mouse coordinates before clicking the host window.
|
||||
@@ -79,18 +93,17 @@ struct ImGui_ImplOSX_Data
|
||||
id Monitor;
|
||||
NSWindow* Window;
|
||||
|
||||
ImGui_ImplOSX_Data() { memset(this, 0, sizeof(*this)); }
|
||||
ImGui_ImplOSX_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
static ImGui_ImplOSX_Data* ImGui_ImplOSX_CreateBackendData() { return IM_NEW(ImGui_ImplOSX_Data)(); }
|
||||
static ImGui_ImplOSX_Data* ImGui_ImplOSX_GetBackendData() { return (ImGui_ImplOSX_Data*)ImGui::GetIO().BackendPlatformUserData; }
|
||||
static void ImGui_ImplOSX_DestroyBackendData() { IM_DELETE(ImGui_ImplOSX_GetBackendData()); }
|
||||
|
||||
static inline CFTimeInterval GetMachAbsoluteTimeInSeconds() { return (CFTimeInterval)(double)(clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / 1e9); }
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplOSX_InitPlatformInterface();
|
||||
static void ImGui_ImplOSX_ShutdownPlatformInterface();
|
||||
static void ImGui_ImplOSX_InitMultiViewportSupport();
|
||||
static void ImGui_ImplOSX_ShutdownMultiViewportSupport();
|
||||
static void ImGui_ImplOSX_UpdateMonitors();
|
||||
static void ImGui_ImplOSX_AddTrackingArea(NSView* _Nonnull view);
|
||||
static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view);
|
||||
@@ -135,12 +148,28 @@ static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view);
|
||||
|
||||
- (void)updateImePosWithView:(NSView *)view
|
||||
{
|
||||
NSWindow *window = view.window;
|
||||
NSWindow* window = view.window;
|
||||
if (!window)
|
||||
return;
|
||||
NSRect contentRect = [window contentRectForFrameRect:window.frame];
|
||||
NSRect rect = NSMakeRect(_posX, contentRect.size.height - _posY, 0, 0);
|
||||
_imeRect = [window convertRectToScreen:rect];
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
NSRect frame = window.frame;
|
||||
NSRect contentRect = window.contentLayoutRect;
|
||||
if (window.styleMask & NSWindowStyleMaskFullSizeContentView) // No title bar windows should be considered.
|
||||
contentRect = frame;
|
||||
|
||||
NSRect firstScreenFrame = NSScreen.screens[0].frame;
|
||||
_imeRect = NSMakeRect(_posX, _posY, 0, 0);
|
||||
_imeRect.origin.y = firstScreenFrame.size.height - _imeRect.size.height - _imeRect.origin.y; // Opposite of ConvertNSRect()
|
||||
}
|
||||
else
|
||||
{
|
||||
NSRect contentRect = [window contentRectForFrameRect:window.frame];
|
||||
NSRect rect = NSMakeRect(_posX, contentRect.size.height - _posY, 0, 0);
|
||||
_imeRect = [window convertRectToScreen:rect];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)viewDidMoveToWindow
|
||||
@@ -261,7 +290,10 @@ static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view);
|
||||
@end
|
||||
|
||||
// Functions
|
||||
static ImGuiKey ImGui_ImplOSX_KeyCodeToImGuiKey(int key_code)
|
||||
|
||||
// Not static to allow third-party code to use that if they want to (but undocumented)
|
||||
ImGuiKey ImGui_ImplOSX_KeyCodeToImGuiKey(int key_code);
|
||||
ImGuiKey ImGui_ImplOSX_KeyCodeToImGuiKey(int key_code)
|
||||
{
|
||||
switch (key_code)
|
||||
{
|
||||
@@ -345,36 +377,36 @@ static ImGuiKey ImGui_ImplOSX_KeyCodeToImGuiKey(int key_code)
|
||||
case kVK_RightOption: return ImGuiKey_RightAlt;
|
||||
case kVK_RightCommand: return ImGuiKey_RightSuper;
|
||||
// case kVK_Function: return ImGuiKey_;
|
||||
// case kVK_F17: return ImGuiKey_;
|
||||
// case kVK_VolumeUp: return ImGuiKey_;
|
||||
// case kVK_VolumeDown: return ImGuiKey_;
|
||||
// case kVK_Mute: return ImGuiKey_;
|
||||
// case kVK_F18: return ImGuiKey_;
|
||||
// case kVK_F19: return ImGuiKey_;
|
||||
// case kVK_F20: return ImGuiKey_;
|
||||
case kVK_F1: return ImGuiKey_F1;
|
||||
case kVK_F2: return ImGuiKey_F2;
|
||||
case kVK_F3: return ImGuiKey_F3;
|
||||
case kVK_F4: return ImGuiKey_F4;
|
||||
case kVK_F5: return ImGuiKey_F5;
|
||||
case kVK_F6: return ImGuiKey_F6;
|
||||
case kVK_F7: return ImGuiKey_F7;
|
||||
case kVK_F3: return ImGuiKey_F3;
|
||||
case kVK_F8: return ImGuiKey_F8;
|
||||
case kVK_F9: return ImGuiKey_F9;
|
||||
case kVK_F11: return ImGuiKey_F11;
|
||||
case kVK_F13: return ImGuiKey_PrintScreen;
|
||||
// case kVK_F16: return ImGuiKey_;
|
||||
// case kVK_F14: return ImGuiKey_;
|
||||
case kVK_F10: return ImGuiKey_F10;
|
||||
case 0x6E: return ImGuiKey_Menu;
|
||||
case kVK_F11: return ImGuiKey_F11;
|
||||
case kVK_F12: return ImGuiKey_F12;
|
||||
// case kVK_F15: return ImGuiKey_;
|
||||
case kVK_F13: return ImGuiKey_F13;
|
||||
case kVK_F14: return ImGuiKey_F14;
|
||||
case kVK_F15: return ImGuiKey_F15;
|
||||
case kVK_F16: return ImGuiKey_F16;
|
||||
case kVK_F17: return ImGuiKey_F17;
|
||||
case kVK_F18: return ImGuiKey_F18;
|
||||
case kVK_F19: return ImGuiKey_F19;
|
||||
case kVK_F20: return ImGuiKey_F20;
|
||||
case 0x6E: return ImGuiKey_Menu;
|
||||
case kVK_Help: return ImGuiKey_Insert;
|
||||
case kVK_Home: return ImGuiKey_Home;
|
||||
case kVK_PageUp: return ImGuiKey_PageUp;
|
||||
case kVK_ForwardDelete: return ImGuiKey_Delete;
|
||||
case kVK_F4: return ImGuiKey_F4;
|
||||
case kVK_End: return ImGuiKey_End;
|
||||
case kVK_F2: return ImGuiKey_F2;
|
||||
case kVK_PageDown: return ImGuiKey_PageDown;
|
||||
case kVK_F1: return ImGuiKey_F1;
|
||||
case kVK_LeftArrow: return ImGuiKey_LeftArrow;
|
||||
case kVK_RightArrow: return ImGuiKey_RightArrow;
|
||||
case kVK_DownArrow: return ImGuiKey_DownArrow;
|
||||
@@ -399,22 +431,25 @@ IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(void* _Nullable view) {
|
||||
bool ImGui_ImplOSX_Init(NSView* view)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_CreateBackendData();
|
||||
io.BackendPlatformUserData = (void*)bd;
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplOSX_Data* bd = IM_NEW(ImGui_ImplOSX_Data)();
|
||||
io.BackendPlatformUserData = (void*)bd;
|
||||
io.BackendPlatformName = "imgui_impl_osx";
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||
//io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
||||
//io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional)
|
||||
io.BackendPlatformName = "imgui_impl_osx";
|
||||
|
||||
bd->Observer = [ImGuiObserver new];
|
||||
bd->Window = view.window ?: NSApp.orderedWindows.firstObject;
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (__bridge_retained void*)bd->Window;
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplOSX_InitPlatformInterface();
|
||||
ImGui_ImplOSX_UpdateMonitors();
|
||||
ImGui_ImplOSX_InitMultiViewportSupport();
|
||||
|
||||
// Load cursors. Some of them are undocumented.
|
||||
bd->MouseCursorHidden = false;
|
||||
@@ -431,14 +466,14 @@ bool ImGui_ImplOSX_Init(NSView* view)
|
||||
// Note that imgui.cpp also include default OSX clipboard handlers which can be enabled
|
||||
// by adding '#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS' in imconfig.h and adding '-framework ApplicationServices' to your linker command-line.
|
||||
// Since we are already in ObjC land here, it is easy for us to add a clipboard handler using the NSPasteboard api.
|
||||
io.SetClipboardTextFn = [](void*, const char* str) -> void
|
||||
platform_io.Platform_SetClipboardTextFn = [](ImGuiContext*, const char* str) -> void
|
||||
{
|
||||
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
|
||||
[pasteboard declareTypes:[NSArray arrayWithObject:NSPasteboardTypeString] owner:nil];
|
||||
[pasteboard setString:[NSString stringWithUTF8String:str] forType:NSPasteboardTypeString];
|
||||
};
|
||||
|
||||
io.GetClipboardTextFn = [](void*) -> const char*
|
||||
platform_io.Platform_GetClipboardTextFn = [](ImGuiContext*) -> const char*
|
||||
{
|
||||
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
|
||||
NSString* available = [pasteboard availableTypeFromArray: [NSArray arrayWithObject:NSPasteboardTypeString]];
|
||||
@@ -473,7 +508,7 @@ bool ImGui_ImplOSX_Init(NSView* view)
|
||||
[view addSubview:bd->KeyEventResponder];
|
||||
ImGui_ImplOSX_AddTrackingArea(view);
|
||||
|
||||
io.SetPlatformImeDataFn = [](ImGuiViewport* viewport, ImGuiPlatformImeData* data) -> void
|
||||
platform_io.Platform_SetImeDataFn = [](ImGuiContext*, ImGuiViewport* viewport, ImGuiPlatformImeData* data) -> void
|
||||
{
|
||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||
if (data->WantVisible)
|
||||
@@ -494,8 +529,23 @@ bool ImGui_ImplOSX_Init(NSView* view)
|
||||
|
||||
void ImGui_ImplOSX_Shutdown()
|
||||
{
|
||||
ImGui_ImplOSX_ShutdownPlatformInterface();
|
||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:bd->Observer];
|
||||
bd->Observer = nullptr;
|
||||
if (bd->Monitor != nullptr)
|
||||
{
|
||||
[NSEvent removeMonitor:bd->Monitor];
|
||||
bd->Monitor = nullptr;
|
||||
}
|
||||
|
||||
ImGui_ImplOSX_ShutdownMultiViewportSupport();
|
||||
ImGui_ImplOSX_DestroyBackendData();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.BackendPlatformName = nullptr;
|
||||
io.BackendPlatformUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports);
|
||||
}
|
||||
|
||||
static void ImGui_ImplOSX_UpdateMouseCursor()
|
||||
@@ -534,7 +584,6 @@ static void ImGui_ImplOSX_UpdateMouseCursor()
|
||||
static void ImGui_ImplOSX_UpdateGamepads()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
memset(io.NavInputs, 0, sizeof(io.NavInputs));
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
|
||||
return;
|
||||
|
||||
@@ -601,6 +650,7 @@ static void ImGui_ImplOSX_UpdateImePosWithView(NSView* view)
|
||||
void ImGui_ImplOSX_NewFrame(NSView* view)
|
||||
{
|
||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplOSX_Init()?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Setup display size
|
||||
@@ -843,9 +893,11 @@ struct ImGuiViewportDataOSX
|
||||
|
||||
@end
|
||||
|
||||
static void ConvertNSRect(NSScreen* screen, NSRect* r)
|
||||
static void ConvertNSRect(NSRect* r)
|
||||
{
|
||||
r->origin.y = screen.frame.size.height - r->origin.y - r->size.height;
|
||||
NSRect firstScreenFrame = NSScreen.screens[0].frame;
|
||||
IM_ASSERT(firstScreenFrame.origin.x == 0 && firstScreenFrame.origin.y == 0);
|
||||
r->origin.y = firstScreenFrame.size.height - r->origin.y - r->size.height;
|
||||
}
|
||||
|
||||
static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport)
|
||||
@@ -856,7 +908,7 @@ static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport)
|
||||
|
||||
NSScreen* screen = bd->Window.screen;
|
||||
NSRect rect = NSMakeRect(viewport->Pos.x, viewport->Pos.y, viewport->Size.x, viewport->Size.y);
|
||||
ConvertNSRect(screen, &rect);
|
||||
ConvertNSRect(&rect);
|
||||
|
||||
NSWindowStyleMask styleMask = 0;
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoDecoration)
|
||||
@@ -876,7 +928,7 @@ static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport)
|
||||
window.opaque = YES;
|
||||
|
||||
KeyEventResponder* view = [[KeyEventResponder alloc] initWithFrame:rect];
|
||||
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6)
|
||||
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6 && ceil(NSAppKitVersionNumber) < NSAppKitVersionNumber10_15)
|
||||
[view setWantsBestResolutionOpenGLSurface:YES];
|
||||
|
||||
window.contentView = view;
|
||||
@@ -926,11 +978,13 @@ static ImVec2 ImGui_ImplOSX_GetWindowPos(ImGuiViewport* viewport)
|
||||
IM_ASSERT(data->Window != 0);
|
||||
|
||||
NSWindow* window = data->Window;
|
||||
NSScreen* screen = window.screen;
|
||||
NSSize size = screen.frame.size;
|
||||
NSRect frame = window.frame;
|
||||
NSRect rect = window.contentLayoutRect;
|
||||
return ImVec2(frame.origin.x, size.height - frame.origin.y - rect.size.height);
|
||||
NSRect contentRect = window.contentLayoutRect;
|
||||
if (window.styleMask & NSWindowStyleMaskFullSizeContentView) // No title bar windows should be considered.
|
||||
contentRect = frame;
|
||||
|
||||
NSRect firstScreenFrame = NSScreen.screens[0].frame;
|
||||
return ImVec2(frame.origin.x, firstScreenFrame.size.height - frame.origin.y - contentRect.size.height);
|
||||
}
|
||||
|
||||
static void ImGui_ImplOSX_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
|
||||
@@ -942,7 +996,7 @@ static void ImGui_ImplOSX_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
|
||||
NSSize size = window.frame.size;
|
||||
|
||||
NSRect r = NSMakeRect(pos.x, pos.y, size.width, size.height);
|
||||
ConvertNSRect(window.screen, &r);
|
||||
ConvertNSRect(&r);
|
||||
[window setFrameOrigin:r.origin];
|
||||
}
|
||||
|
||||
@@ -1023,10 +1077,15 @@ static void ImGui_ImplOSX_UpdateMonitors()
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Monitors.resize(0);
|
||||
|
||||
NSRect firstScreenFrame = NSScreen.screens[0].frame;
|
||||
IM_ASSERT(firstScreenFrame.origin.x == 0 && firstScreenFrame.origin.y == 0);
|
||||
|
||||
for (NSScreen* screen in NSScreen.screens)
|
||||
{
|
||||
NSRect frame = screen.frame;
|
||||
NSRect visibleFrame = screen.visibleFrame;
|
||||
ConvertNSRect(&frame);
|
||||
ConvertNSRect(&visibleFrame);
|
||||
|
||||
ImGuiPlatformMonitor imgui_monitor;
|
||||
imgui_monitor.MainPos = ImVec2(frame.origin.x, frame.origin.y);
|
||||
@@ -1034,15 +1093,15 @@ static void ImGui_ImplOSX_UpdateMonitors()
|
||||
imgui_monitor.WorkPos = ImVec2(visibleFrame.origin.x, visibleFrame.origin.y);
|
||||
imgui_monitor.WorkSize = ImVec2(visibleFrame.size.width, visibleFrame.size.height);
|
||||
imgui_monitor.DpiScale = screen.backingScaleFactor;
|
||||
imgui_monitor.PlatformHandle = (__bridge_retained void*)screen;
|
||||
|
||||
platform_io.Monitors.push_back(imgui_monitor);
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplOSX_InitPlatformInterface()
|
||||
static void ImGui_ImplOSX_InitMultiViewportSupport()
|
||||
{
|
||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||
ImGui_ImplOSX_UpdateMonitors();
|
||||
|
||||
// Register platform interface (will be coupled with a renderer interface)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
@@ -1074,7 +1133,7 @@ static void ImGui_ImplOSX_InitPlatformInterface()
|
||||
object:nil];
|
||||
}
|
||||
|
||||
static void ImGui_ImplOSX_ShutdownPlatformInterface()
|
||||
static void ImGui_ImplOSX_ShutdownMultiViewportSupport()
|
||||
{
|
||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
||||
[NSNotificationCenter.defaultCenter removeObserver:bd->Observer
|
||||
@@ -1094,3 +1153,7 @@ static void ImGui_ImplOSX_ShutdownPlatformInterface()
|
||||
main_viewport->PlatformUserData = nullptr;
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+1209
File diff suppressed because it is too large
Load Diff
+50
@@ -0,0 +1,50 @@
|
||||
// dear imgui: Platform Backend for SDL2
|
||||
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
|
||||
// (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Clipboard support.
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// Missing features or Issues:
|
||||
// [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
struct SDL_Window;
|
||||
struct SDL_Renderer;
|
||||
struct _SDL_GameController;
|
||||
typedef union SDL_Event SDL_Event;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForOther(SDL_Window* window);
|
||||
IMGUI_IMPL_API void ImGui_ImplSDL2_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDL2_NewFrame();
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event);
|
||||
|
||||
// Gamepad selection automatically starts in AutoFirst mode, picking first available SDL_Gamepad. You may override this.
|
||||
// When using manual mode, caller is responsible for opening/closing gamepad.
|
||||
enum ImGui_ImplSDL2_GamepadMode { ImGui_ImplSDL2_GamepadMode_AutoFirst, ImGui_ImplSDL2_GamepadMode_AutoAll, ImGui_ImplSDL2_GamepadMode_Manual };
|
||||
IMGUI_IMPL_API void ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode mode, struct _SDL_GameController** manual_gamepads_array = nullptr, int manual_gamepads_count = -1);
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
+1161
File diff suppressed because it is too large
Load Diff
+50
@@ -0,0 +1,50 @@
|
||||
// dear imgui: Platform Backend for SDL3
|
||||
// This needs to be used along with a Renderer (e.g. SDL_GPU, DirectX11, OpenGL3, Vulkan..)
|
||||
// (Info: SDL3 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Clipboard support.
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [x] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable' -> the OS animation effect when window gets created/destroyed is problematic. SDL2 backend doesn't have issue.
|
||||
// Missing features or Issues:
|
||||
// [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||
// [x] Platform: IME support. Position somehow broken in SDL3 + app needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
struct SDL_Window;
|
||||
struct SDL_Renderer;
|
||||
struct SDL_Gamepad;
|
||||
typedef union SDL_Event SDL_Event;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForOpenGL(SDL_Window* window, void* sdl_gl_context);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForVulkan(SDL_Window* window);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForD3D(SDL_Window* window);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForMetal(SDL_Window* window);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForSDLGPU(SDL_Window* window);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForOther(SDL_Window* window);
|
||||
IMGUI_IMPL_API void ImGui_ImplSDL3_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDL3_NewFrame();
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event);
|
||||
|
||||
// Gamepad selection automatically starts in AutoFirst mode, picking first available SDL_Gamepad. You may override this.
|
||||
// When using manual mode, caller is responsible for opening/closing gamepad.
|
||||
enum ImGui_ImplSDL3_GamepadMode { ImGui_ImplSDL3_GamepadMode_AutoFirst, ImGui_ImplSDL3_GamepadMode_AutoAll, ImGui_ImplSDL3_GamepadMode_Manual };
|
||||
IMGUI_IMPL_API void ImGui_ImplSDL3_SetGamepadMode(ImGui_ImplSDL3_GamepadMode mode, SDL_Gamepad** manual_gamepads_array = nullptr, int manual_gamepads_count = -1);
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
+617
@@ -0,0 +1,617 @@
|
||||
// dear imgui: Renderer Backend for SDL_GPU
|
||||
// This needs to be used along with the SDL3 Platform Backend
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use simply cast a reference to your SDL_GPUTextureSamplerBinding to ImTextureID.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
||||
|
||||
// The aim of imgui_impl_sdlgpu3.h/.cpp is to be usable in your engine without any modification.
|
||||
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// Important note to the reader who wish to integrate imgui_impl_sdlgpu3.cpp/.h in their own engine/app.
|
||||
// - Unlike other backends, the user must call the function Imgui_ImplSDLGPU3_PrepareDrawData() BEFORE issuing a SDL_GPURenderPass containing ImGui_ImplSDLGPU3_RenderDrawData.
|
||||
// Calling the function is MANDATORY, otherwise the ImGui will not upload neither the vertex nor the index buffer for the GPU. See imgui_impl_sdlgpu3.cpp for more info.
|
||||
|
||||
// CHANGELOG
|
||||
// 2025-01-16: Renamed ImGui_ImplSDLGPU3_InitInfo::GpuDevice to Device.
|
||||
// 2025-01-09: SDL_GPU: Added the SDL_GPU3 backend.
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_sdlgpu3.h"
|
||||
#include "imgui_impl_sdlgpu3_shaders.h"
|
||||
|
||||
// SDL_GPU Data
|
||||
|
||||
// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplSDLGPU3_RenderDrawData()
|
||||
struct ImGui_ImplSDLGPU3_FrameData
|
||||
{
|
||||
SDL_GPUBuffer* VertexBuffer = nullptr;
|
||||
SDL_GPUBuffer* IndexBuffer = nullptr;
|
||||
uint32_t VertexBufferSize = 0;
|
||||
uint32_t IndexBufferSize = 0;
|
||||
};
|
||||
|
||||
struct ImGui_ImplSDLGPU3_Data
|
||||
{
|
||||
ImGui_ImplSDLGPU3_InitInfo InitInfo;
|
||||
|
||||
// Graphics pipeline & shaders
|
||||
SDL_GPUShader* VertexShader = nullptr;
|
||||
SDL_GPUShader* FragmentShader = nullptr;
|
||||
SDL_GPUGraphicsPipeline* Pipeline = nullptr;
|
||||
|
||||
// Font data
|
||||
SDL_GPUSampler* FontSampler = nullptr;
|
||||
SDL_GPUTexture* FontTexture = nullptr;
|
||||
SDL_GPUTextureSamplerBinding FontBinding = { nullptr, nullptr };
|
||||
|
||||
// Frame data for main window
|
||||
ImGui_ImplSDLGPU3_FrameData MainWindowFrameData;
|
||||
};
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplSDLGPU3_DestroyFrameData();
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FUNCTIONS
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||
// FIXME: multi-context support has never been tested.
|
||||
static ImGui_ImplSDLGPU3_Data* ImGui_ImplSDLGPU3_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLGPU3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLGPU3_SetupRenderState(ImDrawData* draw_data, SDL_GPUGraphicsPipeline* pipeline, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass * render_pass, ImGui_ImplSDLGPU3_FrameData* fd, uint32_t fb_width, uint32_t fb_height)
|
||||
{
|
||||
//ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
|
||||
// Bind graphics pipeline
|
||||
SDL_BindGPUGraphicsPipeline(render_pass,pipeline);
|
||||
|
||||
// Bind Vertex And Index Buffers
|
||||
if (draw_data->TotalVtxCount > 0)
|
||||
{
|
||||
SDL_GPUBufferBinding vertex_buffer_binding = {};
|
||||
vertex_buffer_binding.buffer = fd->VertexBuffer;
|
||||
vertex_buffer_binding.offset = 0;
|
||||
SDL_GPUBufferBinding index_buffer_binding = {};
|
||||
index_buffer_binding.buffer = fd->IndexBuffer;
|
||||
index_buffer_binding.offset = 0;
|
||||
SDL_BindGPUVertexBuffers(render_pass,0, &vertex_buffer_binding, 1);
|
||||
SDL_BindGPUIndexBuffer(render_pass, &index_buffer_binding, sizeof(ImDrawIdx) == 2 ? SDL_GPU_INDEXELEMENTSIZE_16BIT : SDL_GPU_INDEXELEMENTSIZE_32BIT);
|
||||
}
|
||||
|
||||
// Setup viewport
|
||||
SDL_GPUViewport viewport = {};
|
||||
viewport.x = 0;
|
||||
viewport.y = 0;
|
||||
viewport.w = (float)fb_width;
|
||||
viewport.h = (float)fb_height;
|
||||
viewport.min_depth = 0.0f;
|
||||
viewport.max_depth = 1.0f;
|
||||
SDL_SetGPUViewport(render_pass, &viewport);
|
||||
|
||||
// Setup scale and translation
|
||||
// Our visible imgui space lies from draw_data->DisplayPps (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||
struct UBO { float scale[2]; float translation[2]; } ubo;
|
||||
ubo.scale[0] = 2.0f / draw_data->DisplaySize.x;
|
||||
ubo.scale[1] = 2.0f / draw_data->DisplaySize.y;
|
||||
ubo.translation[0] = -1.0f - draw_data->DisplayPos.x * ubo.scale[0];
|
||||
ubo.translation[1] = -1.0f - draw_data->DisplayPos.y * ubo.scale[1];
|
||||
SDL_PushGPUVertexUniformData(command_buffer, 0, &ubo, sizeof(UBO));
|
||||
}
|
||||
|
||||
static void CreateOrResizeBuffer(SDL_GPUBuffer** buffer, uint32_t* old_size, uint32_t new_size, SDL_GPUBufferUsageFlags usage)
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||
|
||||
// Even though this is fairly rarely called.
|
||||
SDL_WaitForGPUIdle(v->Device);
|
||||
SDL_ReleaseGPUBuffer(v->Device, *buffer);
|
||||
|
||||
SDL_GPUBufferCreateInfo buffer_info = {};
|
||||
buffer_info.usage = usage;
|
||||
buffer_info.size = new_size;
|
||||
buffer_info.props = 0;
|
||||
*buffer = SDL_CreateGPUBuffer(v->Device, &buffer_info);
|
||||
*old_size = new_size;
|
||||
IM_ASSERT(*buffer != nullptr && "Failed to create GPU Buffer, call SDL_GetError() for more information");
|
||||
}
|
||||
|
||||
// SDL_GPU doesn't allow copy passes to occur while a render or compute pass is bound!
|
||||
// The only way to allow a user to supply their own RenderPass (to render to a texture instead of the window for example),
|
||||
// is to split the upload part of ImGui_ImplSDLGPU3_RenderDrawData() to another function that needs to be called by the user before rendering.
|
||||
void Imgui_ImplSDLGPU3_PrepareDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer)
|
||||
{
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
if (fb_width <= 0 || fb_height <= 0 || draw_data->TotalVtxCount <= 0)
|
||||
return;
|
||||
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||
ImGui_ImplSDLGPU3_FrameData* fd = &bd->MainWindowFrameData;
|
||||
|
||||
uint32_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert);
|
||||
uint32_t index_size = draw_data->TotalIdxCount * sizeof(ImDrawIdx);
|
||||
if (fd->VertexBuffer == nullptr || fd->VertexBufferSize < vertex_size)
|
||||
CreateOrResizeBuffer(&fd->VertexBuffer, &fd->VertexBufferSize, vertex_size, SDL_GPU_BUFFERUSAGE_VERTEX);
|
||||
if (fd->IndexBuffer == nullptr || fd->IndexBufferSize < index_size)
|
||||
CreateOrResizeBuffer(&fd->IndexBuffer, &fd->IndexBufferSize, index_size, SDL_GPU_BUFFERUSAGE_INDEX);
|
||||
|
||||
// FIXME: It feels like more code could be shared there.
|
||||
SDL_GPUTransferBufferCreateInfo vertex_transferbuffer_info = {};
|
||||
vertex_transferbuffer_info.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD;
|
||||
vertex_transferbuffer_info.size = vertex_size;
|
||||
SDL_GPUTransferBufferCreateInfo index_transferbuffer_info = {};
|
||||
index_transferbuffer_info.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD;
|
||||
index_transferbuffer_info.size = index_size;
|
||||
|
||||
SDL_GPUTransferBuffer* vertex_transferbuffer = SDL_CreateGPUTransferBuffer(v->Device, &vertex_transferbuffer_info);
|
||||
IM_ASSERT(vertex_transferbuffer != nullptr && "Failed to create the vertex transfer buffer, call SDL_GetError() for more information");
|
||||
SDL_GPUTransferBuffer* index_transferbuffer = SDL_CreateGPUTransferBuffer(v->Device, &index_transferbuffer_info);
|
||||
IM_ASSERT(index_transferbuffer != nullptr && "Failed to create the index transfer buffer, call SDL_GetError() for more information");
|
||||
|
||||
ImDrawVert* vtx_dst = (ImDrawVert*)SDL_MapGPUTransferBuffer(v->Device, vertex_transferbuffer, true);
|
||||
ImDrawIdx* idx_dst = (ImDrawIdx*)SDL_MapGPUTransferBuffer(v->Device, index_transferbuffer, true);
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
idx_dst += draw_list->IdxBuffer.Size;
|
||||
}
|
||||
SDL_UnmapGPUTransferBuffer(v->Device, vertex_transferbuffer);
|
||||
SDL_UnmapGPUTransferBuffer(v->Device, index_transferbuffer);
|
||||
|
||||
SDL_GPUTransferBufferLocation vertex_buffer_location = {};
|
||||
vertex_buffer_location.offset = 0;
|
||||
vertex_buffer_location.transfer_buffer = vertex_transferbuffer;
|
||||
SDL_GPUTransferBufferLocation index_buffer_location = {};
|
||||
index_buffer_location.offset = 0;
|
||||
index_buffer_location.transfer_buffer = index_transferbuffer;
|
||||
|
||||
SDL_GPUBufferRegion vertex_buffer_region = {};
|
||||
vertex_buffer_region.buffer = fd->VertexBuffer;
|
||||
vertex_buffer_region.offset = 0;
|
||||
vertex_buffer_region.size = vertex_size;
|
||||
|
||||
SDL_GPUBufferRegion index_buffer_region = {};
|
||||
index_buffer_region.buffer = fd->IndexBuffer;
|
||||
index_buffer_region.offset = 0;
|
||||
index_buffer_region.size = index_size;
|
||||
|
||||
SDL_GPUCopyPass* copy_pass = SDL_BeginGPUCopyPass(command_buffer);
|
||||
SDL_UploadToGPUBuffer(copy_pass, &vertex_buffer_location, &vertex_buffer_region, true);
|
||||
SDL_UploadToGPUBuffer(copy_pass, &index_buffer_location, &index_buffer_region, true);
|
||||
SDL_EndGPUCopyPass(copy_pass);
|
||||
SDL_ReleaseGPUTransferBuffer(v->Device, index_transferbuffer);
|
||||
SDL_ReleaseGPUTransferBuffer(v->Device, vertex_transferbuffer);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass* render_pass, SDL_GPUGraphicsPipeline* pipeline)
|
||||
{
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
if (fb_width <= 0 || fb_height <= 0)
|
||||
return;
|
||||
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_FrameData* fd = &bd->MainWindowFrameData;
|
||||
|
||||
if (pipeline == nullptr)
|
||||
pipeline = bd->Pipeline;
|
||||
|
||||
ImGui_ImplSDLGPU3_SetupRenderState(draw_data, pipeline, command_buffer, render_pass, fd, fb_width, fb_height);
|
||||
|
||||
// Will project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
|
||||
|
||||
// Render command lists
|
||||
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||
int global_vtx_offset = 0;
|
||||
int global_idx_offset = 0;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||
|
||||
// Clamp to viewport as SDL_SetGPUScissor() won't accept values that are off bounds
|
||||
if (clip_min.x < 0.0f) { clip_min.x = 0.0f; }
|
||||
if (clip_min.y < 0.0f) { clip_min.y = 0.0f; }
|
||||
if (clip_max.x > fb_width) { clip_max.x = (float)fb_width; }
|
||||
if (clip_max.y > fb_height) { clip_max.y = (float)fb_height; }
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
// Apply scissor/clipping rectangle
|
||||
SDL_Rect scissor_rect = {};
|
||||
scissor_rect.x = (int)clip_min.x;
|
||||
scissor_rect.y = (int)clip_min.y;
|
||||
scissor_rect.w = (int)(clip_max.x - clip_min.x);
|
||||
scissor_rect.h = (int)(clip_max.y - clip_min.y);
|
||||
SDL_SetGPUScissor(render_pass,&scissor_rect);
|
||||
|
||||
// Bind DescriptorSet with font or user texture
|
||||
SDL_BindGPUFragmentSamplers(render_pass, 0, (SDL_GPUTextureSamplerBinding*)pcmd->GetTexID(), 1);
|
||||
|
||||
// Draw
|
||||
SDL_DrawGPUIndexedPrimitives(render_pass, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||
}
|
||||
}
|
||||
global_idx_offset += draw_list->IdxBuffer.Size;
|
||||
global_vtx_offset += draw_list->VtxBuffer.Size;
|
||||
}
|
||||
|
||||
// Note: at this point both SDL_SetGPUViewport() and SDL_SetGPUScissor() have been called.
|
||||
// Our last values will leak into user/application rendering if you forgot to call SDL_SetGPUViewport() and SDL_SetGPUScissor() yourself to explicitly set that state
|
||||
// In theory we should aim to backup/restore those values but I am not sure this is possible.
|
||||
// We perform a call to SDL_SetGPUScissor() to set back a full viewport which is likely to fix things for 99% users but technically this is not perfect. (See github #4644)
|
||||
SDL_Rect scissor_rect { 0, 0, fb_width, fb_height };
|
||||
SDL_SetGPUScissor(render_pass, &scissor_rect);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLGPU3_CreateFontsTexture()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||
|
||||
// Destroy existing texture (if any)
|
||||
if (bd->FontTexture)
|
||||
{
|
||||
SDL_WaitForGPUIdle(v->Device);
|
||||
ImGui_ImplSDLGPU3_DestroyFontsTexture();
|
||||
}
|
||||
|
||||
unsigned char* pixels;
|
||||
int width, height;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||
uint32_t upload_size = width * height * 4 * sizeof(char);
|
||||
|
||||
// Create the Image:
|
||||
{
|
||||
SDL_GPUTextureCreateInfo texture_info = {};
|
||||
texture_info.type = SDL_GPU_TEXTURETYPE_2D;
|
||||
texture_info.format = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM;
|
||||
texture_info.usage = SDL_GPU_TEXTUREUSAGE_SAMPLER;
|
||||
texture_info.width = width;
|
||||
texture_info.height = height;
|
||||
texture_info.layer_count_or_depth = 1;
|
||||
texture_info.num_levels = 1;
|
||||
texture_info.sample_count = SDL_GPU_SAMPLECOUNT_1;
|
||||
|
||||
bd->FontTexture = SDL_CreateGPUTexture(v->Device, &texture_info);
|
||||
IM_ASSERT(bd->FontTexture && "Failed to create font texture, call SDL_GetError() for more info");
|
||||
}
|
||||
|
||||
// Assign the texture to the TextureSamplerBinding
|
||||
bd->FontBinding.texture = bd->FontTexture;
|
||||
|
||||
// Create all the upload structures and upload:
|
||||
{
|
||||
SDL_GPUTransferBufferCreateInfo transferbuffer_info = {};
|
||||
transferbuffer_info.usage = SDL_GPU_TRANSFERBUFFERUSAGE_UPLOAD;
|
||||
transferbuffer_info.size = upload_size;
|
||||
|
||||
SDL_GPUTransferBuffer* transferbuffer = SDL_CreateGPUTransferBuffer(v->Device, &transferbuffer_info);
|
||||
IM_ASSERT(transferbuffer != nullptr && "Failed to create font transfer buffer, call SDL_GetError() for more information");
|
||||
|
||||
void* texture_ptr = SDL_MapGPUTransferBuffer(v->Device, transferbuffer, false);
|
||||
memcpy(texture_ptr, pixels, upload_size);
|
||||
SDL_UnmapGPUTransferBuffer(v->Device, transferbuffer);
|
||||
|
||||
SDL_GPUTextureTransferInfo transfer_info = {};
|
||||
transfer_info.offset = 0;
|
||||
transfer_info.transfer_buffer = transferbuffer;
|
||||
|
||||
SDL_GPUTextureRegion texture_region = {};
|
||||
texture_region.texture = bd->FontTexture;
|
||||
texture_region.w = width;
|
||||
texture_region.h = height;
|
||||
texture_region.d = 1;
|
||||
|
||||
SDL_GPUCommandBuffer* cmd = SDL_AcquireGPUCommandBuffer(v->Device);
|
||||
SDL_GPUCopyPass* copy_pass = SDL_BeginGPUCopyPass(cmd);
|
||||
SDL_UploadToGPUTexture(copy_pass, &transfer_info, &texture_region, false);
|
||||
SDL_EndGPUCopyPass(copy_pass);
|
||||
SDL_SubmitGPUCommandBuffer(cmd);
|
||||
SDL_ReleaseGPUTransferBuffer(v->Device, transferbuffer);
|
||||
}
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID((ImTextureID)&bd->FontBinding);
|
||||
}
|
||||
|
||||
// You probably never need to call this, as it is called by ImGui_ImplSDLGPU3_CreateFontsTexture() and ImGui_ImplSDLGPU3_Shutdown().
|
||||
void ImGui_ImplSDLGPU3_DestroyFontsTexture()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||
if (bd->FontTexture)
|
||||
{
|
||||
SDL_ReleaseGPUTexture(v->Device, bd->FontTexture);
|
||||
bd->FontBinding.texture = nullptr;
|
||||
bd->FontTexture = nullptr;
|
||||
}
|
||||
io.Fonts->SetTexID(0);
|
||||
}
|
||||
|
||||
static void Imgui_ImplSDLGPU3_CreateShaders()
|
||||
{
|
||||
// Create the shader modules
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||
|
||||
const char* driver = SDL_GetGPUDeviceDriver(v->Device);
|
||||
|
||||
SDL_GPUShaderCreateInfo vertex_shader_info = {};
|
||||
vertex_shader_info.entrypoint = "main";
|
||||
vertex_shader_info.stage = SDL_GPU_SHADERSTAGE_VERTEX;
|
||||
vertex_shader_info.num_uniform_buffers = 1;
|
||||
vertex_shader_info.num_storage_buffers = 0;
|
||||
vertex_shader_info.num_storage_textures = 0;
|
||||
vertex_shader_info.num_samplers = 0;
|
||||
|
||||
SDL_GPUShaderCreateInfo fragment_shader_info = {};
|
||||
fragment_shader_info.entrypoint = "main";
|
||||
fragment_shader_info.stage = SDL_GPU_SHADERSTAGE_FRAGMENT;
|
||||
fragment_shader_info.num_samplers = 1;
|
||||
fragment_shader_info.num_storage_buffers = 0;
|
||||
fragment_shader_info.num_storage_textures = 0;
|
||||
fragment_shader_info.num_uniform_buffers = 0;
|
||||
|
||||
if (strcmp(driver, "vulkan") == 0)
|
||||
{
|
||||
vertex_shader_info.format = SDL_GPU_SHADERFORMAT_SPIRV;
|
||||
vertex_shader_info.code = spirv_vertex;
|
||||
vertex_shader_info.code_size = sizeof(spirv_vertex);
|
||||
fragment_shader_info.format = SDL_GPU_SHADERFORMAT_SPIRV;
|
||||
fragment_shader_info.code = spirv_fragment;
|
||||
fragment_shader_info.code_size = sizeof(spirv_fragment);
|
||||
}
|
||||
else if (strcmp(driver, "direct3d12") == 0)
|
||||
{
|
||||
vertex_shader_info.format = SDL_GPU_SHADERFORMAT_DXBC;
|
||||
vertex_shader_info.code = dxbc_vertex;
|
||||
vertex_shader_info.code_size = sizeof(dxbc_vertex);
|
||||
fragment_shader_info.format = SDL_GPU_SHADERFORMAT_DXBC;
|
||||
fragment_shader_info.code = dxbc_fragment;
|
||||
fragment_shader_info.code_size = sizeof(dxbc_fragment);
|
||||
}
|
||||
#ifdef __APPLE__
|
||||
else
|
||||
{
|
||||
vertex_shader_info.entrypoint = "main0";
|
||||
vertex_shader_info.format = SDL_GPU_SHADERFORMAT_METALLIB;
|
||||
vertex_shader_info.code = metallib_vertex;
|
||||
vertex_shader_info.code_size = sizeof(metallib_vertex);
|
||||
fragment_shader_info.entrypoint = "main0";
|
||||
fragment_shader_info.format = SDL_GPU_SHADERFORMAT_METALLIB;
|
||||
fragment_shader_info.code = metallib_fragment;
|
||||
fragment_shader_info.code_size = sizeof(metallib_fragment);
|
||||
}
|
||||
#endif
|
||||
bd->VertexShader = SDL_CreateGPUShader(v->Device, &vertex_shader_info);
|
||||
bd->FragmentShader = SDL_CreateGPUShader(v->Device, &fragment_shader_info);
|
||||
IM_ASSERT(bd->VertexShader != nullptr && "Failed to create vertex shader, call SDL_GetError() for more information");
|
||||
IM_ASSERT(bd->FragmentShader != nullptr && "Failed to create fragment shader, call SDL_GetError() for more information");
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLGPU3_CreateGraphicsPipeline()
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||
Imgui_ImplSDLGPU3_CreateShaders();
|
||||
|
||||
SDL_GPUVertexBufferDescription vertex_buffer_desc[1];
|
||||
vertex_buffer_desc[0].slot = 0;
|
||||
vertex_buffer_desc[0].input_rate = SDL_GPU_VERTEXINPUTRATE_VERTEX;
|
||||
vertex_buffer_desc[0].instance_step_rate = 0;
|
||||
vertex_buffer_desc[0].pitch = sizeof(ImDrawVert);
|
||||
|
||||
SDL_GPUVertexAttribute vertex_attributes[3];
|
||||
vertex_attributes[0].buffer_slot = 0;
|
||||
vertex_attributes[0].format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2;
|
||||
vertex_attributes[0].location = 0;
|
||||
vertex_attributes[0].offset = offsetof(ImDrawVert,pos);
|
||||
|
||||
vertex_attributes[1].buffer_slot = 0;
|
||||
vertex_attributes[1].format = SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2;
|
||||
vertex_attributes[1].location = 1;
|
||||
vertex_attributes[1].offset = offsetof(ImDrawVert, uv);
|
||||
|
||||
vertex_attributes[2].buffer_slot = 0;
|
||||
vertex_attributes[2].format = SDL_GPU_VERTEXELEMENTFORMAT_UBYTE4_NORM;
|
||||
vertex_attributes[2].location = 2;
|
||||
vertex_attributes[2].offset = offsetof(ImDrawVert, col);
|
||||
|
||||
SDL_GPUVertexInputState vertex_input_state = {};
|
||||
vertex_input_state.num_vertex_attributes = 3;
|
||||
vertex_input_state.vertex_attributes = vertex_attributes;
|
||||
vertex_input_state.num_vertex_buffers = 1;
|
||||
vertex_input_state.vertex_buffer_descriptions = vertex_buffer_desc;
|
||||
|
||||
SDL_GPURasterizerState rasterizer_state = {};
|
||||
rasterizer_state.fill_mode = SDL_GPU_FILLMODE_FILL;
|
||||
rasterizer_state.cull_mode = SDL_GPU_CULLMODE_NONE;
|
||||
rasterizer_state.front_face = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE;
|
||||
rasterizer_state.enable_depth_bias = false;
|
||||
rasterizer_state.enable_depth_clip = false;
|
||||
|
||||
SDL_GPUMultisampleState multisample_state = {};
|
||||
multisample_state.sample_count = v->MSAASamples;
|
||||
multisample_state.enable_mask = false;
|
||||
|
||||
SDL_GPUDepthStencilState depth_stencil_state = {};
|
||||
depth_stencil_state.enable_depth_test = false;
|
||||
depth_stencil_state.enable_depth_write = false;
|
||||
depth_stencil_state.enable_stencil_test = false;
|
||||
|
||||
SDL_GPUColorTargetBlendState blend_state = {};
|
||||
blend_state.enable_blend = true;
|
||||
blend_state.src_color_blendfactor = SDL_GPU_BLENDFACTOR_SRC_ALPHA;
|
||||
blend_state.dst_color_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
blend_state.color_blend_op = SDL_GPU_BLENDOP_ADD;
|
||||
blend_state.src_alpha_blendfactor = SDL_GPU_BLENDFACTOR_ONE;
|
||||
blend_state.dst_alpha_blendfactor = SDL_GPU_BLENDFACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
blend_state.alpha_blend_op = SDL_GPU_BLENDOP_ADD;
|
||||
blend_state.color_write_mask = SDL_GPU_COLORCOMPONENT_R | SDL_GPU_COLORCOMPONENT_G | SDL_GPU_COLORCOMPONENT_B | SDL_GPU_COLORCOMPONENT_A;
|
||||
|
||||
SDL_GPUColorTargetDescription color_target_desc[1];
|
||||
color_target_desc[0].format = v->ColorTargetFormat;
|
||||
color_target_desc[0].blend_state = blend_state;
|
||||
|
||||
SDL_GPUGraphicsPipelineTargetInfo target_info = {};
|
||||
target_info.num_color_targets = 1;
|
||||
target_info.color_target_descriptions = color_target_desc;
|
||||
target_info.has_depth_stencil_target = false;
|
||||
|
||||
SDL_GPUGraphicsPipelineCreateInfo pipeline_info = {};
|
||||
pipeline_info.vertex_shader = bd->VertexShader;
|
||||
pipeline_info.fragment_shader = bd->FragmentShader;
|
||||
pipeline_info.vertex_input_state = vertex_input_state;
|
||||
pipeline_info.primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST;
|
||||
pipeline_info.rasterizer_state = rasterizer_state;
|
||||
pipeline_info.multisample_state = multisample_state;
|
||||
pipeline_info.depth_stencil_state = depth_stencil_state;
|
||||
pipeline_info.target_info = target_info;
|
||||
|
||||
bd->Pipeline = SDL_CreateGPUGraphicsPipeline(v->Device, &pipeline_info);
|
||||
IM_ASSERT(bd->Pipeline != nullptr && "Failed to create graphics pipeline, call SDL_GetError() for more information");
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLGPU3_CreateDeviceObjects()
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||
|
||||
if (!bd->FontSampler)
|
||||
{
|
||||
// Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling.
|
||||
SDL_GPUSamplerCreateInfo sampler_info = {};
|
||||
sampler_info.min_filter = SDL_GPU_FILTER_LINEAR;
|
||||
sampler_info.mag_filter = SDL_GPU_FILTER_LINEAR;
|
||||
sampler_info.mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_LINEAR;
|
||||
sampler_info.address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
|
||||
sampler_info.address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
|
||||
sampler_info.address_mode_w = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE;
|
||||
sampler_info.mip_lod_bias = 0.0f;
|
||||
sampler_info.min_lod = -1000.0f;
|
||||
sampler_info.max_lod = 1000.0f;
|
||||
sampler_info.enable_anisotropy = false;
|
||||
sampler_info.max_anisotropy = 1.0f;
|
||||
sampler_info.enable_compare = false;
|
||||
|
||||
bd->FontSampler = SDL_CreateGPUSampler(v->Device, &sampler_info);
|
||||
bd->FontBinding.sampler = bd->FontSampler;
|
||||
IM_ASSERT(bd->FontSampler != nullptr && "Failed to create font sampler, call SDL_GetError() for more information");
|
||||
}
|
||||
|
||||
ImGui_ImplSDLGPU3_CreateGraphicsPipeline();
|
||||
ImGui_ImplSDLGPU3_CreateFontsTexture();
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLGPU3_DestroyFrameData()
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||
|
||||
SDL_ReleaseGPUBuffer(v->Device, bd->MainWindowFrameData.VertexBuffer);
|
||||
SDL_ReleaseGPUBuffer(v->Device, bd->MainWindowFrameData.IndexBuffer);
|
||||
bd->MainWindowFrameData.VertexBuffer = nullptr;
|
||||
bd->MainWindowFrameData.IndexBuffer = nullptr;
|
||||
bd->MainWindowFrameData.VertexBufferSize = 0;
|
||||
bd->MainWindowFrameData.IndexBufferSize = 0;
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLGPU3_DestroyDeviceObjects()
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_InitInfo* v = &bd->InitInfo;
|
||||
|
||||
ImGui_ImplSDLGPU3_DestroyFrameData();
|
||||
ImGui_ImplSDLGPU3_DestroyFontsTexture();
|
||||
|
||||
if (bd->VertexShader) { SDL_ReleaseGPUShader(v->Device, bd->VertexShader); bd->VertexShader = nullptr;}
|
||||
if (bd->FragmentShader) { SDL_ReleaseGPUShader(v->Device, bd->FragmentShader); bd->FragmentShader = nullptr;}
|
||||
if (bd->FontSampler) { SDL_ReleaseGPUSampler(v->Device, bd->FontSampler); bd->FontSampler = nullptr;}
|
||||
if (bd->Pipeline) { SDL_ReleaseGPUGraphicsPipeline(v->Device, bd->Pipeline); bd->Pipeline = nullptr;}
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDLGPU3_Init(ImGui_ImplSDLGPU3_InitInfo* info)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplSDLGPU3_Data* bd = IM_NEW(ImGui_ImplSDLGPU3_Data)();
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_sdlgpu3";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
|
||||
IM_ASSERT(info->Device != nullptr);
|
||||
IM_ASSERT(info->ColorTargetFormat != SDL_GPU_TEXTUREFORMAT_INVALID);
|
||||
|
||||
bd->InitInfo = *info;
|
||||
|
||||
ImGui_ImplSDLGPU3_CreateDeviceObjects();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLGPU3_Shutdown()
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplSDLGPU3_DestroyDeviceObjects();
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLGPU3_NewFrame()
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDLGPU3_Init()?");
|
||||
|
||||
if (!bd->FontTexture)
|
||||
ImGui_ImplSDLGPU3_CreateFontsTexture();
|
||||
}
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
// dear imgui: Renderer Backend for SDL_GPU
|
||||
// This needs to be used along with the SDL3 Platform Backend
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use simply cast a reference to your SDL_GPUTextureSamplerBinding to ImTextureID.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
||||
|
||||
// The aim of imgui_impl_sdlgpu3.h/.cpp is to be usable in your engine without any modification.
|
||||
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// Important note to the reader who wish to integrate imgui_impl_sdlgpu3.cpp/.h in their own engine/app.
|
||||
// - Unline other backends, the user must call the function Imgui_ImplSDLGPU_PrepareDrawData BEFORE issuing a SDL_GPURenderPass containing ImGui_ImplSDLGPU_RenderDrawData.
|
||||
// Calling the function is MANDATORY, otherwise the ImGui will not upload neither the vertex nor the index buffer for the GPU. See imgui_impl_sdlgpu3.cpp for more info.
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include <SDL3/SDL_gpu.h>
|
||||
|
||||
// Initialization data, for ImGui_ImplSDLGPU_Init()
|
||||
// - Remember to set ColorTargetFormat to the correct format. If you're rendering to the swapchain, call SDL_GetGPUSwapchainTextureFormat to query the right value
|
||||
struct ImGui_ImplSDLGPU3_InitInfo
|
||||
{
|
||||
SDL_GPUDevice* Device = nullptr;
|
||||
SDL_GPUTextureFormat ColorTargetFormat = SDL_GPU_TEXTUREFORMAT_INVALID;
|
||||
SDL_GPUSampleCount MSAASamples = SDL_GPU_SAMPLECOUNT_1;
|
||||
};
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDLGPU3_Init(ImGui_ImplSDLGPU3_InitInfo* info);
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_NewFrame();
|
||||
IMGUI_IMPL_API void Imgui_ImplSDLGPU3_PrepareDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer);
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass* render_pass, SDL_GPUGraphicsPipeline* pipeline = nullptr);
|
||||
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_DestroyDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_CreateFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_DestroyFontsTexture();
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
@@ -0,0 +1,372 @@
|
||||
#pragma once
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include <stdint.h>
|
||||
|
||||
// Data exported using
|
||||
// misc/fonts/binary_to_compressed_c.exe -u8 -nocompress filename symbolname >filename.h
|
||||
// With some manual pasting.
|
||||
|
||||
// Check sdlgpu3/ folder for the shaders' source code and instruction on how to build them
|
||||
const uint8_t spirv_vertex[1732] = {
|
||||
3,2,35,7,0,0,1,0,11,0,13,0,55,0,0,0,0,0,0,0,17,0,2,0,1,0,0,0,11,0,6,0,1,0,0,0,71,76,83,76,46,115,116,100,46,52,53,48,0,0,0,0,14,0,3,0,0,0,0,0,1,0,0,0,15,0,10,0,0,0,0,0,4,0,0,0,109,
|
||||
97,105,110,0,0,0,0,11,0,0,0,15,0,0,0,21,0,0,0,30,0,0,0,31,0,0,0,3,0,3,0,2,0,0,0,194,1,0,0,4,0,10,0,71,76,95,71,79,79,71,76,69,95,99,112,112,95,115,116,121,108,101,95,108,105,110,101,
|
||||
95,100,105,114,101,99,116,105,118,101,0,0,4,0,8,0,71,76,95,71,79,79,71,76,69,95,105,110,99,108,117,100,101,95,100,105,114,101,99,116,105,118,101,0,5,0,4,0,4,0,0,0,109,97,105,110,0,
|
||||
0,0,0,5,0,3,0,9,0,0,0,0,0,0,0,6,0,5,0,9,0,0,0,0,0,0,0,67,111,108,111,114,0,0,0,6,0,4,0,9,0,0,0,1,0,0,0,85,86,0,0,5,0,3,0,11,0,0,0,79,117,116,0,5,0,4,0,15,0,0,0,97,67,111,108,111,114,
|
||||
0,0,5,0,3,0,21,0,0,0,97,85,86,0,5,0,6,0,28,0,0,0,103,108,95,80,101,114,86,101,114,116,101,120,0,0,0,0,6,0,6,0,28,0,0,0,0,0,0,0,103,108,95,80,111,115,105,116,105,111,110,0,6,0,7,0,28,
|
||||
0,0,0,1,0,0,0,103,108,95,80,111,105,110,116,83,105,122,101,0,0,0,0,6,0,7,0,28,0,0,0,2,0,0,0,103,108,95,67,108,105,112,68,105,115,116,97,110,99,101,0,6,0,7,0,28,0,0,0,3,0,0,0,103,108,
|
||||
95,67,117,108,108,68,105,115,116,97,110,99,101,0,5,0,3,0,30,0,0,0,0,0,0,0,5,0,4,0,31,0,0,0,97,80,111,115,0,0,0,0,5,0,6,0,33,0,0,0,117,80,117,115,104,67,111,110,115,116,97,110,116,0,
|
||||
0,0,6,0,5,0,33,0,0,0,0,0,0,0,117,83,99,97,108,101,0,0,6,0,6,0,33,0,0,0,1,0,0,0,117,84,114,97,110,115,108,97,116,101,0,0,5,0,3,0,35,0,0,0,112,99,0,0,71,0,4,0,11,0,0,0,30,0,0,0,0,0,0,
|
||||
0,71,0,4,0,15,0,0,0,30,0,0,0,2,0,0,0,71,0,4,0,21,0,0,0,30,0,0,0,1,0,0,0,71,0,3,0,28,0,0,0,2,0,0,0,72,0,5,0,28,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,72,0,5,0,28,0,0,0,1,0,0,0,11,0,0,0,1,0,
|
||||
0,0,72,0,5,0,28,0,0,0,2,0,0,0,11,0,0,0,3,0,0,0,72,0,5,0,28,0,0,0,3,0,0,0,11,0,0,0,4,0,0,0,71,0,4,0,31,0,0,0,30,0,0,0,0,0,0,0,71,0,3,0,33,0,0,0,2,0,0,0,72,0,5,0,33,0,0,0,0,0,0,0,35,
|
||||
0,0,0,0,0,0,0,72,0,5,0,33,0,0,0,1,0,0,0,35,0,0,0,8,0,0,0,71,0,4,0,35,0,0,0,33,0,0,0,0,0,0,0,71,0,4,0,35,0,0,0,34,0,0,0,1,0,0,0,19,0,2,0,2,0,0,0,33,0,3,0,3,0,0,0,2,0,0,0,22,0,3,0,6,
|
||||
0,0,0,32,0,0,0,23,0,4,0,7,0,0,0,6,0,0,0,4,0,0,0,23,0,4,0,8,0,0,0,6,0,0,0,2,0,0,0,30,0,4,0,9,0,0,0,7,0,0,0,8,0,0,0,32,0,4,0,10,0,0,0,3,0,0,0,9,0,0,0,59,0,4,0,10,0,0,0,11,0,0,0,3,0,0,
|
||||
0,21,0,4,0,12,0,0,0,32,0,0,0,1,0,0,0,43,0,4,0,12,0,0,0,13,0,0,0,0,0,0,0,32,0,4,0,14,0,0,0,1,0,0,0,7,0,0,0,59,0,4,0,14,0,0,0,15,0,0,0,1,0,0,0,32,0,4,0,17,0,0,0,3,0,0,0,7,0,0,0,43,0,
|
||||
4,0,12,0,0,0,19,0,0,0,1,0,0,0,32,0,4,0,20,0,0,0,1,0,0,0,8,0,0,0,59,0,4,0,20,0,0,0,21,0,0,0,1,0,0,0,32,0,4,0,23,0,0,0,3,0,0,0,8,0,0,0,21,0,4,0,25,0,0,0,32,0,0,0,0,0,0,0,43,0,4,0,25,
|
||||
0,0,0,26,0,0,0,1,0,0,0,28,0,4,0,27,0,0,0,6,0,0,0,26,0,0,0,30,0,6,0,28,0,0,0,7,0,0,0,6,0,0,0,27,0,0,0,27,0,0,0,32,0,4,0,29,0,0,0,3,0,0,0,28,0,0,0,59,0,4,0,29,0,0,0,30,0,0,0,3,0,0,0,
|
||||
59,0,4,0,20,0,0,0,31,0,0,0,1,0,0,0,30,0,4,0,33,0,0,0,8,0,0,0,8,0,0,0,32,0,4,0,34,0,0,0,2,0,0,0,33,0,0,0,59,0,4,0,34,0,0,0,35,0,0,0,2,0,0,0,32,0,4,0,36,0,0,0,2,0,0,0,8,0,0,0,43,0,4,
|
||||
0,6,0,0,0,43,0,0,0,0,0,0,0,43,0,4,0,6,0,0,0,44,0,0,0,0,0,128,63,43,0,4,0,6,0,0,0,49,0,0,0,0,0,128,191,32,0,4,0,50,0,0,0,3,0,0,0,6,0,0,0,54,0,5,0,2,0,0,0,4,0,0,0,0,0,0,0,3,0,0,0,248,
|
||||
0,2,0,5,0,0,0,61,0,4,0,7,0,0,0,16,0,0,0,15,0,0,0,65,0,5,0,17,0,0,0,18,0,0,0,11,0,0,0,13,0,0,0,62,0,3,0,18,0,0,0,16,0,0,0,61,0,4,0,8,0,0,0,22,0,0,0,21,0,0,0,65,0,5,0,23,0,0,0,24,0,0,
|
||||
0,11,0,0,0,19,0,0,0,62,0,3,0,24,0,0,0,22,0,0,0,61,0,4,0,8,0,0,0,32,0,0,0,31,0,0,0,65,0,5,0,36,0,0,0,37,0,0,0,35,0,0,0,13,0,0,0,61,0,4,0,8,0,0,0,38,0,0,0,37,0,0,0,133,0,5,0,8,0,0,0,
|
||||
39,0,0,0,32,0,0,0,38,0,0,0,65,0,5,0,36,0,0,0,40,0,0,0,35,0,0,0,19,0,0,0,61,0,4,0,8,0,0,0,41,0,0,0,40,0,0,0,129,0,5,0,8,0,0,0,42,0,0,0,39,0,0,0,41,0,0,0,81,0,5,0,6,0,0,0,45,0,0,0,42,
|
||||
0,0,0,0,0,0,0,81,0,5,0,6,0,0,0,46,0,0,0,42,0,0,0,1,0,0,0,80,0,7,0,7,0,0,0,47,0,0,0,45,0,0,0,46,0,0,0,43,0,0,0,44,0,0,0,65,0,5,0,17,0,0,0,48,0,0,0,30,0,0,0,13,0,0,0,62,0,3,0,48,0,0,
|
||||
0,47,0,0,0,65,0,6,0,50,0,0,0,51,0,0,0,30,0,0,0,13,0,0,0,26,0,0,0,61,0,4,0,6,0,0,0,52,0,0,0,51,0,0,0,133,0,5,0,6,0,0,0,53,0,0,0,52,0,0,0,49,0,0,0,65,0,6,0,50,0,0,0,54,0,0,0,30,0,0,0,
|
||||
13,0,0,0,26,0,0,0,62,0,3,0,54,0,0,0,53,0,0,0,253,0,1,0,56,0,1,0,
|
||||
};
|
||||
const uint8_t spirv_fragment[844] = {
|
||||
3,2,35,7,0,0,1,0,11,0,13,0,30,0,0,0,0,0,0,0,17,0,2,0,1,0,0,0,11,0,6,0,1,0,0,0,71,76,83,76,46,115,116,100,46,52,53,48,0,0,0,0,14,0,3,0,0,0,0,0,1,0,0,0,15,0,7,0,4,0,0,0,4,0,0,0,109,97,
|
||||
105,110,0,0,0,0,9,0,0,0,13,0,0,0,16,0,3,0,4,0,0,0,7,0,0,0,3,0,3,0,2,0,0,0,194,1,0,0,4,0,10,0,71,76,95,71,79,79,71,76,69,95,99,112,112,95,115,116,121,108,101,95,108,105,110,101,95,100,
|
||||
105,114,101,99,116,105,118,101,0,0,4,0,8,0,71,76,95,71,79,79,71,76,69,95,105,110,99,108,117,100,101,95,100,105,114,101,99,116,105,118,101,0,5,0,4,0,4,0,0,0,109,97,105,110,0,0,0,0,5,
|
||||
0,4,0,9,0,0,0,102,67,111,108,111,114,0,0,5,0,3,0,11,0,0,0,0,0,0,0,6,0,5,0,11,0,0,0,0,0,0,0,67,111,108,111,114,0,0,0,6,0,4,0,11,0,0,0,1,0,0,0,85,86,0,0,5,0,3,0,13,0,0,0,73,110,0,0,5,
|
||||
0,5,0,22,0,0,0,115,84,101,120,116,117,114,101,0,0,0,0,71,0,4,0,9,0,0,0,30,0,0,0,0,0,0,0,71,0,4,0,13,0,0,0,30,0,0,0,0,0,0,0,71,0,4,0,22,0,0,0,33,0,0,0,0,0,0,0,71,0,4,0,22,0,0,0,34,0,
|
||||
0,0,2,0,0,0,19,0,2,0,2,0,0,0,33,0,3,0,3,0,0,0,2,0,0,0,22,0,3,0,6,0,0,0,32,0,0,0,23,0,4,0,7,0,0,0,6,0,0,0,4,0,0,0,32,0,4,0,8,0,0,0,3,0,0,0,7,0,0,0,59,0,4,0,8,0,0,0,9,0,0,0,3,0,0,0,23,
|
||||
0,4,0,10,0,0,0,6,0,0,0,2,0,0,0,30,0,4,0,11,0,0,0,7,0,0,0,10,0,0,0,32,0,4,0,12,0,0,0,1,0,0,0,11,0,0,0,59,0,4,0,12,0,0,0,13,0,0,0,1,0,0,0,21,0,4,0,14,0,0,0,32,0,0,0,1,0,0,0,43,0,4,0,
|
||||
14,0,0,0,15,0,0,0,0,0,0,0,32,0,4,0,16,0,0,0,1,0,0,0,7,0,0,0,25,0,9,0,19,0,0,0,6,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,27,0,3,0,20,0,0,0,19,0,0,0,32,0,4,0,21,0,0,0,0,
|
||||
0,0,0,20,0,0,0,59,0,4,0,21,0,0,0,22,0,0,0,0,0,0,0,43,0,4,0,14,0,0,0,24,0,0,0,1,0,0,0,32,0,4,0,25,0,0,0,1,0,0,0,10,0,0,0,54,0,5,0,2,0,0,0,4,0,0,0,0,0,0,0,3,0,0,0,248,0,2,0,5,0,0,0,65,
|
||||
0,5,0,16,0,0,0,17,0,0,0,13,0,0,0,15,0,0,0,61,0,4,0,7,0,0,0,18,0,0,0,17,0,0,0,61,0,4,0,20,0,0,0,23,0,0,0,22,0,0,0,65,0,5,0,25,0,0,0,26,0,0,0,13,0,0,0,24,0,0,0,61,0,4,0,10,0,0,0,27,0,
|
||||
0,0,26,0,0,0,87,0,5,0,7,0,0,0,28,0,0,0,23,0,0,0,27,0,0,0,133,0,5,0,7,0,0,0,29,0,0,0,18,0,0,0,28,0,0,0,62,0,3,0,9,0,0,0,29,0,0,0,253,0,1,0,56,0,1,0,
|
||||
};
|
||||
|
||||
const uint8_t dxbc_vertex[1064] = {
|
||||
68,88,66,67,32,50,127,204,241,196,165,104,216,114,216,116,220,164,29,45,1,0,0,0,40,4,0,0,5,0,0,0,52,0,0,0,136,1,0,0,236,1,0,0,92,2,0,0,140,3,0,0,82,68,69,70,76,1,0,0,1,0,0,0,116,0,
|
||||
0,0,1,0,0,0,60,0,0,0,1,5,254,255,0,5,0,0,34,1,0,0,19,19,68,37,60,0,0,0,24,0,0,0,40,0,0,0,40,0,0,0,36,0,0,0,12,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
|
||||
0,1,0,0,0,1,0,0,0,0,0,0,0,117,80,117,115,104,67,111,110,115,116,97,110,116,0,171,171,100,0,0,0,2,0,0,0,140,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,220,0,0,0,0,0,0,0,8,0,0,0,2,0,0,0,240,0,0,
|
||||
0,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,20,1,0,0,8,0,0,0,8,0,0,0,2,0,0,0,240,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,255,255,255,255,0,0,0,0,112,99,95,117,83,99,97,
|
||||
108,101,0,102,108,111,97,116,50,0,171,171,171,1,0,3,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,0,0,0,112,99,95,117,84,114,97,110,115,108,97,116,101,0,77,105,99,114,
|
||||
111,115,111,102,116,32,40,82,41,32,72,76,83,76,32,83,104,97,100,101,114,32,67,111,109,112,105,108,101,114,32,49,48,46,49,0,171,171,73,83,71,78,92,0,0,0,3,0,0,0,8,0,0,0,80,0,0,0,0,0,
|
||||
0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,3,0,0,80,0,0,0,1,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,3,3,0,0,80,0,0,0,2,0,0,0,0,0,0,0,3,0,0,0,2,0,0,0,15,15,0,0,84,69,88,67,79,79,82,68,0,171,171,171,79,83,
|
||||
71,78,104,0,0,0,3,0,0,0,8,0,0,0,80,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,15,0,0,0,80,0,0,0,1,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,3,12,0,0,89,0,0,0,0,0,0,0,1,0,0,0,3,0,0,0,2,0,0,0,15,0,0,
|
||||
0,84,69,88,67,79,79,82,68,0,83,86,95,80,111,115,105,116,105,111,110,0,171,171,171,83,72,69,88,40,1,0,0,81,0,1,0,74,0,0,0,106,8,0,1,89,0,0,7,70,142,48,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
|
||||
0,0,1,0,0,0,95,0,0,3,50,16,16,0,0,0,0,0,95,0,0,3,50,16,16,0,1,0,0,0,95,0,0,3,242,16,16,0,2,0,0,0,101,0,0,3,242,32,16,0,0,0,0,0,101,0,0,3,50,32,16,0,1,0,0,0,103,0,0,4,242,32,16,0,2,
|
||||
0,0,0,1,0,0,0,104,0,0,2,1,0,0,0,50,0,0,13,50,0,16,0,0,0,0,0,70,16,16,0,0,0,0,0,70,128,48,0,0,0,0,0,0,0,0,0,0,0,0,0,230,138,48,0,0,0,0,0,0,0,0,0,0,0,0,0,54,0,0,6,34,32,16,0,2,0,0,0,
|
||||
26,0,16,128,65,0,0,0,0,0,0,0,54,0,0,5,242,32,16,0,0,0,0,0,70,30,16,0,2,0,0,0,54,0,0,5,18,32,16,0,2,0,0,0,10,0,16,0,0,0,0,0,54,0,0,8,194,32,16,0,2,0,0,0,2,64,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,128,63,54,0,0,5,50,32,16,0,1,0,0,0,70,16,16,0,1,0,0,0,62,0,0,1,83,84,65,84,148,0,0,0,7,0,0,0,1,0,0,0,0,0,0,0,6,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
};
|
||||
const uint8_t dxbc_fragment[744] = {
|
||||
68,88,66,67,235,219,43,109,38,151,39,223,98,41,193,28,215,98,67,110,1,0,0,0,232,2,0,0,5,0,0,0,52,0,0,0,12,1,0,0,88,1,0,0,140,1,0,0,76,2,0,0,82,68,69,70,208,0,0,0,0,0,0,0,0,0,0,0,2,
|
||||
0,0,0,60,0,0,0,1,5,255,255,0,5,0,0,167,0,0,0,19,19,68,37,60,0,0,0,24,0,0,0,40,0,0,0,40,0,0,0,36,0,0,0,12,0,0,0,0,0,0,0,140,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,
|
||||
0,0,2,0,0,0,0,0,0,0,158,0,0,0,2,0,0,0,5,0,0,0,4,0,0,0,255,255,255,255,0,0,0,0,1,0,0,0,12,0,0,0,2,0,0,0,0,0,0,0,95,115,84,101,120,116,117,114,101,95,115,97,109,112,108,101,114,0,115,
|
||||
84,101,120,116,117,114,101,0,77,105,99,114,111,115,111,102,116,32,40,82,41,32,72,76,83,76,32,83,104,97,100,101,114,32,67,111,109,112,105,108,101,114,32,49,48,46,49,0,171,73,83,71,78,
|
||||
68,0,0,0,2,0,0,0,8,0,0,0,56,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,15,15,0,0,56,0,0,0,1,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,3,3,0,0,84,69,88,67,79,79,82,68,0,171,171,171,79,83,71,78,44,0,
|
||||
0,0,1,0,0,0,8,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,15,0,0,0,83,86,95,84,97,114,103,101,116,0,171,171,83,72,69,88,184,0,0,0,81,0,0,0,46,0,0,0,106,8,0,1,90,0,0,6,70,110,48,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,88,24,0,7,70,126,48,0,0,0,0,0,0,0,0,0,0,0,0,0,85,85,0,0,2,0,0,0,98,16,0,3,242,16,16,0,0,0,0,0,98,16,0,3,50,16,16,0,1,0,0,0,101,0,0,3,242,32,16,0,0,
|
||||
0,0,0,104,0,0,2,1,0,0,0,69,0,0,11,242,0,16,0,0,0,0,0,70,16,16,0,1,0,0,0,70,126,32,0,0,0,0,0,0,0,0,0,0,96,32,0,0,0,0,0,0,0,0,0,56,0,0,7,242,32,16,0,0,0,0,0,70,14,16,0,0,0,0,0,70,30,
|
||||
16,0,0,0,0,0,62,0,0,1,83,84,65,84,148,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
};
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <TargetConditionals.h>
|
||||
#if TARGET_OS_MAC
|
||||
const uint8_t metallib_vertex[3892] = {
|
||||
77,84,76,66,1,128,2,0,7,0,0,129,14,0,0,0,52,15,0,0,0,0,0,0,88,0,0,0,0,0,0,0,123,0,0,0,0,0,0,0,219,0,0,0,0,0,0,0,49,0,0,0,0,0,0,0,12,1,0,0,0,0,0,0,8,0,0,0,0,0,0,0,20,1,0,0,0,0,0,0,32,
|
||||
14,0,0,0,0,0,0,1,0,0,0,123,0,0,0,78,65,77,69,6,0,109,97,105,110,48,0,84,89,80,69,1,0,0,72,65,83,72,32,0,62,81,190,157,8,240,236,158,164,213,65,62,170,226,96,136,231,243,238,160,100,
|
||||
26,13,254,254,64,19,129,180,3,149,75,77,68,83,90,8,0,32,14,0,0,0,0,0,0,79,70,70,84,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,69,82,83,8,0,2,0,6,0,3,0,1,0,69,78,68,84,
|
||||
69,78,68,84,45,0,0,0,86,65,84,84,24,0,3,0,97,80,111,115,0,0,128,97,85,86,0,1,128,97,67,111,108,111,114,0,2,128,86,65,84,89,5,0,3,0,4,4,6,69,78,68,84,4,0,0,0,69,78,68,84,222,192,23,
|
||||
11,0,0,0,0,20,0,0,0,8,14,0,0,255,255,255,255,66,67,192,222,53,20,0,0,3,0,0,0,98,12,48,36,128,16,5,200,20,0,0,0,33,12,0,0,74,3,0,0,11,2,33,0,2,0,0,0,22,0,0,0,7,129,35,145,65,200,4,73,
|
||||
6,16,50,57,146,1,132,12,37,5,8,25,30,4,139,98,128,16,69,2,66,146,11,66,132,16,50,20,56,8,24,75,10,50,66,136,72,112,196,33,35,68,18,135,140,16,65,146,2,100,200,8,177,20,32,67,70,136,
|
||||
32,201,1,50,66,132,24,42,40,42,144,49,124,176,92,145,32,196,200,0,0,0,137,32,0,0,24,0,0,0,50,34,8,9,32,98,70,0,33,43,36,152,16,33,37,36,152,16,25,39,12,133,164,144,96,66,100,92,32,
|
||||
36,100,130,224,153,1,24,70,32,128,97,4,1,184,67,72,32,37,77,17,37,76,62,149,82,210,193,57,141,52,1,205,148,4,145,65,4,66,48,197,136,68,145,13,4,204,17,128,129,10,228,28,1,40,12,34,
|
||||
8,194,48,2,145,140,0,0,0,0,0,81,24,0,0,100,0,0,0,27,246,35,248,255,255,255,255,1,48,5,192,15,0,56,0,254,0,144,0,10,232,3,34,28,224,1,30,228,225,29,240,161,13,204,161,30,220,97,28,218,
|
||||
192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,128,48,7,121,8,135,118,40,135,54,128,135,119,72,7,119,160,135,114,144,7,32,28,216,129,29,0,162,29,210,193,29,218,128,29,
|
||||
202,225,28,194,129,29,218,192,30,202,97,28,232,225,29,228,161,13,238,33,29,200,129,30,208,1,136,3,57,192,3,96,112,135,119,104,3,113,168,135,116,96,7,122,72,7,119,152,7,128,112,135,
|
||||
119,104,131,116,112,7,115,152,135,54,48,7,120,104,131,118,8,7,122,64,7,128,30,228,161,30,202,1,32,220,225,29,218,192,29,194,193,29,230,161,13,204,1,30,218,160,29,194,129,30,208,1,160,
|
||||
7,121,168,135,114,0,8,119,120,135,54,152,135,116,56,7,119,40,7,114,104,3,125,40,7,121,120,135,121,104,3,115,128,135,54,104,135,112,160,7,116,0,232,65,30,234,161,28,0,194,29,222,161,
|
||||
13,232,65,30,194,1,30,224,33,29,220,225,28,218,160,29,194,129,30,208,1,160,7,121,168,135,114,0,136,121,160,135,112,24,135,117,104,3,120,144,135,119,160,135,114,24,7,122,120,7,121,104,
|
||||
3,113,168,7,115,48,135,114,144,135,54,152,135,116,208,135,114,0,240,0,32,234,193,29,230,33,28,204,161,28,218,192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,96,195,24,8,
|
||||
4,176,0,164,0,84,65,128,4,105,0,13,225,144,14,242,208,6,226,80,15,230,96,14,229,32,15,109,224,14,239,208,6,225,192,14,233,16,14,243,0,0,0,73,24,0,0,1,0,0,0,19,132,64,0,19,176,112,72,
|
||||
7,121,176,3,58,104,131,112,128,7,120,96,135,114,104,131,118,8,135,113,120,135,121,192,135,56,160,3,55,128,3,55,128,131,13,183,81,14,109,0,15,122,96,7,116,160,7,118,64,7,122,96,7,116,
|
||||
208,6,233,16,7,122,128,7,122,128,7,109,144,14,120,160,7,120,160,7,120,208,6,233,16,7,118,160,7,113,96,7,122,16,7,118,208,6,233,48,7,114,160,7,115,32,7,122,48,7,114,208,6,233,96,7,116,
|
||||
160,7,118,64,7,122,96,7,116,208,6,230,48,7,114,160,7,115,32,7,122,48,7,114,208,6,230,96,7,116,160,7,118,64,7,122,96,7,116,208,6,246,16,7,118,160,7,113,96,7,122,16,7,118,208,6,246,32,
|
||||
7,116,160,7,115,32,7,122,48,7,114,208,6,246,48,7,114,160,7,115,32,7,122,48,7,114,208,6,246,64,7,120,160,7,118,64,7,122,96,7,116,208,6,246,96,7,116,160,7,118,64,7,122,96,7,116,208,6,
|
||||
246,144,7,118,160,7,113,32,7,120,160,7,113,32,7,120,208,6,246,16,7,114,128,7,122,16,7,114,128,7,122,16,7,114,128,7,109,96,15,113,144,7,114,160,7,114,80,7,118,160,7,114,80,7,118,208,
|
||||
6,246,32,7,117,96,7,122,32,7,117,96,7,122,32,7,117,96,7,109,96,15,117,16,7,114,160,7,117,16,7,114,160,7,117,16,7,114,208,6,246,16,7,112,32,7,116,160,7,113,0,7,114,64,7,122,16,7,112,
|
||||
32,7,116,208,6,238,128,7,122,16,7,118,160,7,115,32,7,26,33,12,89,48,0,210,208,67,42,160,48,0,0,8,0,0,0,4,0,0,0,0,0,10,64,98,131,64,81,166,1,0,128,44,16,0,11,0,0,0,50,30,152,16,25,17,
|
||||
76,144,140,9,38,71,198,4,67,202,34,40,129,66,40,135,242,41,64,129,130,40,144,98,24,1,40,3,218,17,0,210,177,132,39,0,0,0,177,24,0,0,165,0,0,0,51,8,128,28,196,225,28,102,20,1,61,136,
|
||||
67,56,132,195,140,66,128,7,121,120,7,115,152,113,12,230,0,15,237,16,14,244,128,14,51,12,66,30,194,193,29,206,161,28,102,48,5,61,136,67,56,132,131,27,204,3,61,200,67,61,140,3,61,204,
|
||||
120,140,116,112,7,123,8,7,121,72,135,112,112,7,122,112,3,118,120,135,112,32,135,25,204,17,14,236,144,14,225,48,15,110,48,15,227,240,14,240,80,14,51,16,196,29,222,33,28,216,33,29,194,
|
||||
97,30,102,48,137,59,188,131,59,208,67,57,180,3,60,188,131,60,132,3,59,204,240,20,118,96,7,123,104,7,55,104,135,114,104,7,55,128,135,112,144,135,112,96,7,118,40,7,118,248,5,118,120,
|
||||
135,119,128,135,95,8,135,113,24,135,114,152,135,121,152,129,44,238,240,14,238,224,14,245,192,14,236,48,3,98,200,161,28,228,161,28,204,161,28,228,161,28,220,97,28,202,33,28,196,129,
|
||||
29,202,97,6,214,144,67,57,200,67,57,152,67,57,200,67,57,184,195,56,148,67,56,136,3,59,148,195,47,188,131,60,252,130,59,212,3,59,176,195,12,199,105,135,112,88,135,114,112,131,116,104,
|
||||
7,120,96,135,116,24,135,116,160,135,25,206,83,15,238,0,15,242,80,14,228,144,14,227,64,15,225,32,14,236,80,14,51,32,40,29,220,193,30,194,65,30,210,33,28,220,129,30,220,224,28,228,225,
|
||||
29,234,1,30,102,24,81,56,176,67,58,156,131,59,204,80,36,118,96,7,123,104,7,55,96,135,119,120,7,120,152,81,76,244,144,15,240,80,14,51,30,106,30,202,97,28,232,33,29,222,193,29,126,1,
|
||||
30,228,161,28,204,33,29,240,97,6,84,133,131,56,204,195,59,176,67,61,208,67,57,252,194,60,228,67,59,136,195,59,176,195,140,197,10,135,121,152,135,119,24,135,116,8,7,122,40,7,114,152,
|
||||
129,92,227,16,14,236,192,14,229,80,14,243,48,35,193,210,65,30,228,225,23,216,225,29,222,1,30,102,72,25,59,176,131,61,180,131,27,132,195,56,140,67,57,204,195,60,184,193,57,200,195,59,
|
||||
212,3,60,204,72,180,113,8,7,118,96,7,113,8,135,113,88,135,25,219,198,14,236,96,15,237,224,6,240,32,15,229,48,15,229,32,15,246,80,14,110,16,14,227,48,14,229,48,15,243,224,6,233,224,
|
||||
14,228,80,14,248,48,35,226,236,97,28,194,129,29,216,225,23,236,33,29,230,33,29,196,33,29,216,33,29,232,33,31,102,32,157,59,188,67,61,184,3,57,148,131,57,204,88,188,112,112,7,119,120,
|
||||
7,122,8,7,122,72,135,119,112,135,25,206,135,14,229,16,14,240,16,14,236,192,14,239,48,14,243,144,14,244,80,14,51,40,48,8,135,116,144,7,55,48,135,122,112,135,113,160,135,116,120,7,119,
|
||||
248,133,115,144,135,119,168,7,120,152,7,0,0,0,0,121,32,0,0,26,1,0,0,114,30,72,32,67,136,12,25,9,114,50,72,32,35,129,140,145,145,209,68,160,16,40,100,60,49,50,66,142,144,33,163,152,
|
||||
6,100,208,82,0,0,0,139,210,88,216,6,109,80,28,20,27,71,6,209,18,25,76,178,24,6,179,64,18,49,24,202,131,68,148,161,68,87,35,0,0,0,0,83,68,75,32,86,101,114,115,105,111,110,119,99,104,
|
||||
97,114,95,115,105,122,101,102,114,97,109,101,45,112,111,105,110,116,101,114,97,105,114,46,109,97,120,95,100,101,118,105,99,101,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,
|
||||
95,99,111,110,115,116,97,110,116,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,104,114,101,97,100,103,114,111,117,112,95,98,117,102,102,101,114,115,97,105,114,46,109,
|
||||
97,120,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,114,101,97,100,95,119,114,105,116,101,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,115,97,109,
|
||||
112,108,101,114,115,65,112,112,108,101,32,109,101,116,97,108,32,118,101,114,115,105,111,110,32,51,50,48,50,51,46,51,54,56,32,40,109,101,116,97,108,102,101,45,51,50,48,50,51,46,51,54,
|
||||
56,41,77,101,116,97,108,97,105,114,46,99,111,109,112,105,108,101,46,100,101,110,111,114,109,115,95,100,105,115,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,97,115,
|
||||
116,95,109,97,116,104,95,101,110,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,114,97,109,101,98,117,102,102,101,114,95,102,101,116,99,104,95,101,110,97,98,108,101,
|
||||
97,105,114,46,118,101,114,116,101,120,95,111,117,116,112,117,116,117,115,101,114,40,108,111,99,110,48,41,97,105,114,46,97,114,103,95,116,121,112,101,95,110,97,109,101,102,108,111,97,
|
||||
116,52,97,105,114,46,97,114,103,95,110,97,109,101,79,117,116,95,67,111,108,111,114,117,115,101,114,40,108,111,99,110,49,41,102,108,111,97,116,50,79,117,116,95,85,86,97,105,114,46,112,
|
||||
111,115,105,116,105,111,110,103,108,95,80,111,115,105,116,105,111,110,97,105,114,46,118,101,114,116,101,120,95,105,110,112,117,116,97,105,114,46,108,111,99,97,116,105,111,110,95,105,
|
||||
110,100,101,120,97,80,111,115,97,85,86,97,67,111,108,111,114,97,105,114,46,98,117,102,102,101,114,97,105,114,46,98,117,102,102,101,114,95,115,105,122,101,97,105,114,46,114,101,97,100,
|
||||
97,105,114,46,97,100,100,114,101,115,115,95,115,112,97,99,101,97,105,114,46,115,116,114,117,99,116,95,116,121,112,101,95,105,110,102,111,117,83,99,97,108,101,117,84,114,97,110,115,
|
||||
108,97,116,101,97,105,114,46,97,114,103,95,116,121,112,101,95,115,105,122,101,97,105,114,46,97,114,103,95,116,121,112,101,95,97,108,105,103,110,95,115,105,122,101,117,80,117,115,104,
|
||||
67,111,110,115,116,97,110,116,112,99,0,0,0,166,119,0,0,0,0,0,0,48,130,144,4,35,8,74,51,130,144,8,35,8,201,48,130,144,16,35,8,73,49,130,144,24,35,8,201,49,130,144,32,35,8,73,50,130,
|
||||
144,40,35,8,201,50,130,112,0,51,12,106,16,172,193,12,3,27,8,109,48,195,224,6,131,26,204,48,184,1,241,6,51,12,110,80,188,193,12,131,27,24,111,48,195,224,6,7,28,204,48,184,1,18,7,51,
|
||||
12,110,144,200,193,12,129,50,195,160,6,115,64,7,51,16,75,29,176,1,29,204,16,48,51,4,205,12,129,51,131,241,64,145,52,81,51,24,79,21,89,211,53,67,129,69,210,148,205,48,152,194,41,160,
|
||||
194,12,9,29,104,27,29,176,65,100,77,220,12,9,27,104,27,27,176,65,100,77,221,12,137,26,104,155,26,176,65,36,77,222,12,10,29,196,1,29,88,100,16,7,113,64,7,86,25,204,64,213,193,7,6,114,
|
||||
176,209,1,27,132,129,24,168,193,24,180,130,25,200,193,25,196,65,132,6,83,26,204,64,168,194,42,176,130,43,204,48,216,65,42,188,194,157,1,192,113,28,199,113,28,199,113,28,199,185,129,
|
||||
27,184,129,27,184,129,27,184,129,27,184,129,69,7,122,96,89,22,29,208,129,27,208,1,46,224,2,46,240,3,122,128,130,140,4,38,40,35,54,54,187,54,151,182,55,178,58,182,50,23,51,182,176,179,
|
||||
185,81,18,59,184,3,60,200,3,61,216,3,62,232,3,63,72,133,141,205,174,205,37,141,172,204,141,110,148,224,15,114,9,75,147,115,177,43,147,155,75,123,115,27,37,0,133,164,194,210,228,92,
|
||||
216,194,220,206,234,194,206,202,190,236,202,228,230,210,222,220,70,9,66,33,167,176,52,57,151,177,183,54,184,52,182,178,175,55,56,186,180,55,183,185,81,6,81,24,5,82,72,37,44,77,206,
|
||||
197,174,76,142,174,12,111,148,224,21,0,0,0,169,24,0,0,37,0,0,0,11,10,114,40,135,119,128,7,122,88,112,152,67,61,184,195,56,176,67,57,208,195,130,230,28,198,161,13,232,65,30,194,193,
|
||||
29,230,33,29,232,33,29,222,193,29,22,52,227,96,14,231,80,15,225,32,15,228,64,15,225,32,15,231,80,14,244,176,128,129,7,121,40,135,112,96,7,118,120,135,113,8,7,122,40,7,114,88,112,156,
|
||||
195,56,180,1,59,164,131,61,148,195,2,107,28,216,33,28,220,225,28,220,32,28,228,97,28,220,32,28,232,129,30,194,97,28,208,161,28,200,97,28,194,129,29,216,97,193,1,15,244,32,15,225,80,
|
||||
15,244,128,14,0,0,0,0,209,16,0,0,6,0,0,0,7,204,60,164,131,59,156,3,59,148,3,61,160,131,60,148,67,56,144,195,1,0,0,0,97,32,0,0,68,0,0,0,19,4,65,44,16,0,0,0,11,0,0,0,148,51,0,180,37,
|
||||
64,61,7,161,72,146,52,7,161,72,9,65,48,26,48,2,48,70,0,130,32,136,127,20,115,16,150,117,97,36,163,1,52,51,0,0,0,0,0,241,48,0,0,32,0,0,0,34,71,200,144,81,18,196,43,0,0,0,0,207,115,89,
|
||||
0,111,109,110,105,112,111,116,101,110,116,32,99,104,97,114,83,105,109,112,108,101,32,67,43,43,32,84,66,65,65,97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,115,40,109,97,105,
|
||||
110,48,41,97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,45,97,114,103,40,51,41,0,19,132,133,89,33,216,194,44,172,24,110,193,22,104,97,67,32,11,27,134,88,192,133,90,216,48,228,
|
||||
66,46,212,194,134,224,22,0,0,157,134,5,146,40,16,130,1,36,254,157,6,103,234,40,16,130,67,0,254,131,12,1,226,12,50,4,138,51,134,48,68,22,128,255,28,195,16,76,179,13,204,5,204,54,4,89,
|
||||
48,219,16,12,194,6,1,49,0,4,0,0,0,91,138,32,200,133,67,23,182,20,68,144,11,135,46,0,0,0,0,0,0,113,32,0,0,3,0,0,0,50,14,16,34,132,0,134,6,0,0,0,0,0,0,0,0,101,12,0,0,31,0,0,0,18,3,148,
|
||||
240,0,0,0,0,3,0,0,0,5,0,0,0,9,0,0,0,76,0,0,0,1,0,0,0,88,0,0,0,0,0,0,0,88,0,0,0,1,0,0,0,112,0,0,0,0,0,0,0,14,0,0,0,24,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0,0,0,0,0,112,0,0,0,0,0,0,0,0,0,0,0,
|
||||
1,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,5,0,0,0,255,255,255,255,0,36,0,0,0,0,0,0,93,12,0,0,13,0,0,0,18,3,148,102,0,0,0,0,109,97,105,110,48,51,50,48,50,51,46,51,54,56,97,105,114,54,
|
||||
52,45,97,112,112,108,101,45,109,97,99,111,115,120,49,52,46,48,46,48,0,0,0,0,0,0,0,0,0,0,
|
||||
};
|
||||
const uint8_t metallib_fragment[3787] = {
|
||||
77,84,76,66,1,128,2,0,7,0,0,129,14,0,0,0,203,14,0,0,0,0,0,0,88,0,0,0,0,0,0,0,123,0,0,0,0,0,0,0,219,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,227,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,235,0,0,0,0,0,0,0,
|
||||
224,13,0,0,0,0,0,0,1,0,0,0,123,0,0,0,78,65,77,69,6,0,109,97,105,110,48,0,84,89,80,69,1,0,1,72,65,83,72,32,0,201,103,233,140,10,95,185,107,79,93,85,82,78,218,248,8,95,184,8,139,191,
|
||||
155,174,56,51,95,203,135,255,117,44,62,77,68,83,90,8,0,224,13,0,0,0,0,0,0,79,70,70,84,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,69,82,83,8,0,2,0,6,0,3,0,1,0,69,78,68,
|
||||
84,69,78,68,84,4,0,0,0,69,78,68,84,4,0,0,0,69,78,68,84,222,192,23,11,0,0,0,0,20,0,0,0,196,13,0,0,255,255,255,255,66,67,192,222,53,20,0,0,3,0,0,0,98,12,48,36,128,16,5,200,20,0,0,0,33,
|
||||
12,0,0,44,3,0,0,11,2,33,0,2,0,0,0,22,0,0,0,7,129,35,145,65,200,4,73,6,16,50,57,146,1,132,12,37,5,8,25,30,4,139,98,128,20,69,2,66,146,11,66,164,16,50,20,56,8,24,75,10,50,82,136,72,112,
|
||||
196,33,35,68,18,135,140,16,65,146,2,100,200,8,177,20,32,67,70,136,32,201,1,50,82,132,24,42,40,42,144,49,124,176,92,145,32,197,200,0,0,0,137,32,0,0,31,0,0,0,50,34,72,9,32,98,70,0,33,
|
||||
43,36,152,20,33,37,36,152,20,25,39,12,133,164,144,96,82,100,92,32,36,101,130,128,154,1,24,70,32,128,27,132,97,4,1,64,74,154,34,74,152,252,127,34,174,137,138,136,223,30,254,105,140,
|
||||
0,24,68,32,2,140,164,41,162,132,201,255,37,128,121,22,34,250,167,49,2,96,16,193,16,76,33,194,40,135,208,28,1,114,132,160,230,8,130,57,2,48,24,70,16,26,163,172,114,6,115,12,128,70,111,
|
||||
32,64,5,218,8,0,0,81,24,0,0,105,0,0,0,27,246,35,248,255,255,255,255,1,104,3,96,13,0,83,0,252,0,144,128,10,232,3,34,28,224,1,30,228,225,29,240,161,13,204,161,30,220,97,28,218,192,28,
|
||||
224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,128,48,7,121,8,135,118,40,135,54,128,135,119,72,7,119,160,135,114,144,7,32,28,216,129,29,0,162,29,210,193,29,218,128,29,202,225,
|
||||
28,194,129,29,218,192,30,202,97,28,232,225,29,228,161,13,238,33,29,200,129,30,208,1,136,3,57,192,3,96,112,135,119,104,3,113,168,135,116,96,7,122,72,7,119,152,7,128,112,135,119,104,
|
||||
131,116,112,7,115,152,135,54,48,7,120,104,131,118,8,7,122,64,7,128,30,228,161,30,202,1,32,220,225,29,218,192,29,194,193,29,230,161,13,204,1,30,218,160,29,194,129,30,208,1,160,7,121,
|
||||
168,135,114,0,8,119,120,135,54,152,135,116,56,7,119,40,7,114,104,3,125,40,7,121,120,135,121,104,3,115,128,135,54,104,135,112,160,7,116,0,232,65,30,234,161,28,0,194,29,222,161,13,232,
|
||||
65,30,194,1,30,224,33,29,220,225,28,218,160,29,194,129,30,208,1,160,7,121,168,135,114,0,136,121,160,135,112,24,135,117,104,3,120,144,135,119,160,135,114,24,7,122,120,7,121,104,3,113,
|
||||
168,7,115,48,135,114,144,135,54,152,135,116,208,135,114,0,240,0,32,234,193,29,230,33,28,204,161,28,218,192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,96,131,33,12,192,
|
||||
2,84,27,140,129,0,22,160,218,0,17,255,255,255,255,63,0,109,0,172,1,96,10,128,31,0,18,80,1,125,176,193,40,2,96,1,170,13,134,33,0,11,80,109,96,142,255,255,255,255,31,128,54,0,214,0,144,
|
||||
128,10,232,3,0,73,24,0,0,4,0,0,0,19,134,64,24,38,12,68,97,76,24,142,194,0,0,0,0,19,176,112,72,7,121,176,3,58,104,131,112,128,7,120,96,135,114,104,131,118,8,135,113,120,135,121,192,
|
||||
135,56,160,3,55,128,3,55,128,131,13,183,81,14,109,0,15,122,96,7,116,160,7,118,64,7,122,96,7,116,208,6,233,16,7,122,128,7,122,128,7,109,144,14,120,160,7,120,160,7,120,208,6,233,16,7,
|
||||
118,160,7,113,96,7,122,16,7,118,208,6,233,48,7,114,160,7,115,32,7,122,48,7,114,208,6,233,96,7,116,160,7,118,64,7,122,96,7,116,208,6,230,48,7,114,160,7,115,32,7,122,48,7,114,208,6,230,
|
||||
96,7,116,160,7,118,64,7,122,96,7,116,208,6,246,16,7,118,160,7,113,96,7,122,16,7,118,208,6,246,32,7,116,160,7,115,32,7,122,48,7,114,208,6,246,48,7,114,160,7,115,32,7,122,48,7,114,208,
|
||||
6,246,64,7,120,160,7,118,64,7,122,96,7,116,208,6,246,96,7,116,160,7,118,64,7,122,96,7,116,208,6,246,144,7,118,160,7,113,32,7,120,160,7,113,32,7,120,208,6,246,16,7,114,128,7,122,16,
|
||||
7,114,128,7,122,16,7,114,128,7,109,96,15,113,144,7,114,160,7,114,80,7,118,160,7,114,80,7,118,208,6,246,32,7,117,96,7,122,32,7,117,96,7,122,32,7,117,96,7,109,96,15,117,16,7,114,160,
|
||||
7,117,16,7,114,160,7,117,16,7,114,208,6,246,16,7,112,32,7,116,160,7,113,0,7,114,64,7,122,16,7,112,32,7,116,208,6,238,128,7,122,16,7,118,160,7,115,32,7,26,33,12,89,48,0,210,208,67,42,
|
||||
160,64,0,0,8,0,0,0,4,0,0,0,0,0,10,96,72,85,108,15,16,0,2,0,0,128,0,0,0,0,0,64,1,72,108,16,40,234,50,0,0,144,5,2,0,0,0,10,0,0,0,50,30,152,16,25,17,76,144,140,9,38,71,198,4,67,106,69,
|
||||
80,2,133,80,14,229,83,128,2,5,81,32,197,48,2,80,6,36,199,18,158,0,0,177,24,0,0,165,0,0,0,51,8,128,28,196,225,28,102,20,1,61,136,67,56,132,195,140,66,128,7,121,120,7,115,152,113,12,
|
||||
230,0,15,237,16,14,244,128,14,51,12,66,30,194,193,29,206,161,28,102,48,5,61,136,67,56,132,131,27,204,3,61,200,67,61,140,3,61,204,120,140,116,112,7,123,8,7,121,72,135,112,112,7,122,
|
||||
112,3,118,120,135,112,32,135,25,204,17,14,236,144,14,225,48,15,110,48,15,227,240,14,240,80,14,51,16,196,29,222,33,28,216,33,29,194,97,30,102,48,137,59,188,131,59,208,67,57,180,3,60,
|
||||
188,131,60,132,3,59,204,240,20,118,96,7,123,104,7,55,104,135,114,104,7,55,128,135,112,144,135,112,96,7,118,40,7,118,248,5,118,120,135,119,128,135,95,8,135,113,24,135,114,152,135,121,
|
||||
152,129,44,238,240,14,238,224,14,245,192,14,236,48,3,98,200,161,28,228,161,28,204,161,28,228,161,28,220,97,28,202,33,28,196,129,29,202,97,6,214,144,67,57,200,67,57,152,67,57,200,67,
|
||||
57,184,195,56,148,67,56,136,3,59,148,195,47,188,131,60,252,130,59,212,3,59,176,195,12,199,105,135,112,88,135,114,112,131,116,104,7,120,96,135,116,24,135,116,160,135,25,206,83,15,238,
|
||||
0,15,242,80,14,228,144,14,227,64,15,225,32,14,236,80,14,51,32,40,29,220,193,30,194,65,30,210,33,28,220,129,30,220,224,28,228,225,29,234,1,30,102,24,81,56,176,67,58,156,131,59,204,80,
|
||||
36,118,96,7,123,104,7,55,96,135,119,120,7,120,152,81,76,244,144,15,240,80,14,51,30,106,30,202,97,28,232,33,29,222,193,29,126,1,30,228,161,28,204,33,29,240,97,6,84,133,131,56,204,195,
|
||||
59,176,67,61,208,67,57,252,194,60,228,67,59,136,195,59,176,195,140,197,10,135,121,152,135,119,24,135,116,8,7,122,40,7,114,152,129,92,227,16,14,236,192,14,229,80,14,243,48,35,193,210,
|
||||
65,30,228,225,23,216,225,29,222,1,30,102,72,25,59,176,131,61,180,131,27,132,195,56,140,67,57,204,195,60,184,193,57,200,195,59,212,3,60,204,72,180,113,8,7,118,96,7,113,8,135,113,88,
|
||||
135,25,219,198,14,236,96,15,237,224,6,240,32,15,229,48,15,229,32,15,246,80,14,110,16,14,227,48,14,229,48,15,243,224,6,233,224,14,228,80,14,248,48,35,226,236,97,28,194,129,29,216,225,
|
||||
23,236,33,29,230,33,29,196,33,29,216,33,29,232,33,31,102,32,157,59,188,67,61,184,3,57,148,131,57,204,88,188,112,112,7,119,120,7,122,8,7,122,72,135,119,112,135,25,206,135,14,229,16,
|
||||
14,240,16,14,236,192,14,239,48,14,243,144,14,244,80,14,51,40,48,8,135,116,144,7,55,48,135,122,112,135,113,160,135,116,120,7,119,248,133,115,144,135,119,168,7,120,152,7,0,0,0,0,121,
|
||||
32,0,0,252,0,0,0,114,30,72,32,67,136,12,25,9,114,50,72,32,35,129,140,145,145,209,68,160,16,40,100,60,49,50,66,142,144,33,163,56,6,220,41,1,0,0,0,139,210,88,216,6,109,80,28,20,27,71,
|
||||
6,81,100,48,134,180,40,15,178,24,197,34,41,24,178,28,13,83,68,75,32,86,101,114,115,105,111,110,119,99,104,97,114,95,115,105,122,101,102,114,97,109,101,45,112,111,105,110,116,101,114,
|
||||
97,105,114,46,109,97,120,95,100,101,118,105,99,101,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,99,111,110,115,116,97,110,116,95,98,117,102,102,101,114,115,97,105,114,
|
||||
46,109,97,120,95,116,104,114,101,97,100,103,114,111,117,112,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,114,
|
||||
101,97,100,95,119,114,105,116,101,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,115,97,109,112,108,101,114,115,65,112,112,108,101,32,109,101,116,97,108,32,118,101,
|
||||
114,115,105,111,110,32,51,50,48,50,51,46,51,54,56,32,40,109,101,116,97,108,102,101,45,51,50,48,50,51,46,51,54,56,41,77,101,116,97,108,97,105,114,46,99,111,109,112,105,108,101,46,100,
|
||||
101,110,111,114,109,115,95,100,105,115,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,97,115,116,95,109,97,116,104,95,101,110,97,98,108,101,97,105,114,46,99,111,109,
|
||||
112,105,108,101,46,102,114,97,109,101,98,117,102,102,101,114,95,102,101,116,99,104,95,101,110,97,98,108,101,97,105,114,46,114,101,110,100,101,114,95,116,97,114,103,101,116,97,105,114,
|
||||
46,97,114,103,95,116,121,112,101,95,110,97,109,101,102,108,111,97,116,52,97,105,114,46,97,114,103,95,110,97,109,101,102,67,111,108,111,114,97,105,114,46,102,114,97,103,109,101,110,
|
||||
116,95,105,110,112,117,116,117,115,101,114,40,108,111,99,110,48,41,97,105,114,46,99,101,110,116,101,114,97,105,114,46,112,101,114,115,112,101,99,116,105,118,101,73,110,95,67,111,108,
|
||||
111,114,117,115,101,114,40,108,111,99,110,49,41,102,108,111,97,116,50,73,110,95,85,86,97,105,114,46,116,101,120,116,117,114,101,97,105,114,46,108,111,99,97,116,105,111,110,95,105,110,
|
||||
100,101,120,97,105,114,46,115,97,109,112,108,101,116,101,120,116,117,114,101,50,100,60,102,108,111,97,116,44,32,115,97,109,112,108,101,62,115,84,101,120,116,117,114,101,97,105,114,
|
||||
46,115,97,109,112,108,101,114,115,97,109,112,108,101,114,115,84,101,120,116,117,114,101,83,109,112,108,114,0,198,96,0,0,0,0,0,0,48,130,208,8,35,8,82,51,130,208,12,35,8,13,49,130,208,
|
||||
20,35,8,141,49,130,208,28,35,8,13,50,130,208,36,35,8,141,50,130,208,44,35,8,13,51,130,144,0,51,12,100,16,148,193,12,131,25,8,103,48,195,128,6,3,25,204,48,160,1,145,6,51,12,104,80,164,
|
||||
193,12,3,26,24,105,48,195,128,6,135,26,204,48,160,1,178,6,51,12,104,144,176,193,12,129,50,195,64,6,109,224,6,51,16,203,27,152,129,27,204,16,48,51,4,205,12,129,51,195,241,184,129,27,
|
||||
64,145,52,205,16,128,194,12,137,27,80,149,117,65,145,132,205,144,152,1,149,89,23,164,73,219,12,10,25,112,157,27,152,129,7,125,18,24,204,144,188,65,24,116,110,96,6,144,24,72,99,48,3,
|
||||
33,10,163,64,10,165,48,195,0,7,161,96,10,71,6,0,199,113,28,199,113,28,199,113,28,231,6,110,224,6,110,224,6,110,224,6,110,224,6,22,29,232,129,101,89,166,192,177,2,43,144,131,58,128,
|
||||
130,140,4,38,40,35,54,54,187,54,151,182,55,178,58,182,50,23,51,182,176,179,185,81,18,56,136,3,57,152,3,58,168,3,59,184,3,60,72,133,141,205,174,205,37,141,172,204,141,110,148,32,15,
|
||||
114,9,75,147,115,177,43,147,155,75,123,115,27,37,208,131,164,194,210,228,92,216,194,220,206,234,194,206,202,190,236,202,228,230,210,222,220,70,9,246,32,167,176,52,57,151,177,183,54,
|
||||
184,52,182,178,175,55,56,186,180,55,183,185,81,6,62,232,3,63,72,38,44,77,206,197,76,46,236,172,173,204,141,110,148,192,20,0,0,0,0,169,24,0,0,37,0,0,0,11,10,114,40,135,119,128,7,122,
|
||||
88,112,152,67,61,184,195,56,176,67,57,208,195,130,230,28,198,161,13,232,65,30,194,193,29,230,33,29,232,33,29,222,193,29,22,52,227,96,14,231,80,15,225,32,15,228,64,15,225,32,15,231,
|
||||
80,14,244,176,128,129,7,121,40,135,112,96,7,118,120,135,113,8,7,122,40,7,114,88,112,156,195,56,180,1,59,164,131,61,148,195,2,107,28,216,33,28,220,225,28,220,32,28,228,97,28,220,32,
|
||||
28,232,129,30,194,97,28,208,161,28,200,97,28,194,129,29,216,97,193,1,15,244,32,15,225,80,15,244,128,14,0,0,0,0,209,16,0,0,6,0,0,0,7,204,60,164,131,59,156,3,59,148,3,61,160,131,60,148,
|
||||
67,56,144,195,1,0,0,0,97,32,0,0,49,0,0,0,19,4,65,44,16,0,0,0,4,0,0,0,196,106,96,4,128,220,8,0,129,17,0,18,51,0,0,0,241,48,0,0,28,0,0,0,34,71,200,144,81,14,196,42,0,0,0,0,23,134,1,0,
|
||||
97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,115,40,109,97,105,110,48,41,97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,45,115,97,109,112,108,101,114,115,97,105,114,
|
||||
45,97,108,105,97,115,45,115,99,111,112,101,45,116,101,120,116,117,114,101,115,0,43,132,85,64,133,21,3,43,172,66,42,172,24,90,97,21,84,97,131,208,10,172,0,0,35,6,205,16,130,96,240,88,
|
||||
135,129,20,3,33,8,204,104,66,0,96,176,136,255,108,3,17,0,27,4,196,0,0,0,2,0,0,0,91,6,224,104,5,0,0,0,0,0,0,0,113,32,0,0,3,0,0,0,50,14,16,34,132,0,251,5,0,0,0,0,0,0,0,0,101,12,0,0,37,
|
||||
0,0,0,18,3,148,40,1,0,0,0,3,0,0,0,32,0,0,0,9,0,0,0,76,0,0,0,1,0,0,0,88,0,0,0,0,0,0,0,88,0,0,0,2,0,0,0,136,0,0,0,0,0,0,0,41,0,0,0,24,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0,0,0,0,0,136,0,0,0,
|
||||
0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,5,0,0,0,255,255,255,255,0,36,0,0,5,0,0,0,27,0,0,0,5,0,0,0,27,0,0,0,255,255,255,255,8,36,0,0,0,0,0,0,93,12,0,0,20,0,0,0,18,3,
|
||||
148,161,0,0,0,0,109,97,105,110,48,97,105,114,46,115,97,109,112,108,101,95,116,101,120,116,117,114,101,95,50,100,46,118,52,102,51,50,51,50,48,50,51,46,51,54,56,97,105,114,54,52,45,97,
|
||||
112,112,108,101,45,109,97,99,111,115,120,49,52,46,48,46,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
};
|
||||
#elif TARGET_OS_IPHONE
|
||||
const uint8_t metallib_vertex[3876] = {
|
||||
77,84,76,66,1,0,2,0,7,0,0,130,18,0,1,0,36,15,0,0,0,0,0,0,88,0,0,0,0,0,0,0,123,0,0,0,0,0,0,0,219,0,0,0,0,0,0,0,49,0,0,0,0,0,0,0,12,1,0,0,0,0,0,0,8,0,0,0,0,0,0,0,20,1,0,0,0,0,0,0,16,
|
||||
14,0,0,0,0,0,0,1,0,0,0,123,0,0,0,78,65,77,69,6,0,109,97,105,110,48,0,84,89,80,69,1,0,0,72,65,83,72,32,0,240,54,230,217,232,66,102,78,35,5,77,235,101,252,229,192,148,96,126,162,111,
|
||||
77,253,247,211,52,17,198,182,137,68,244,77,68,83,90,8,0,16,14,0,0,0,0,0,0,79,70,70,84,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,69,82,83,8,0,2,0,7,0,3,0,2,0,69,78,68,
|
||||
84,69,78,68,84,45,0,0,0,86,65,84,84,24,0,3,0,97,80,111,115,0,0,128,97,85,86,0,1,128,97,67,111,108,111,114,0,2,128,86,65,84,89,5,0,3,0,4,4,6,69,78,68,84,4,0,0,0,69,78,68,84,222,192,
|
||||
23,11,0,0,0,0,20,0,0,0,252,13,0,0,255,255,255,255,66,67,192,222,53,20,0,0,3,0,0,0,98,12,48,36,128,16,5,200,20,0,0,0,33,12,0,0,72,3,0,0,11,2,33,0,2,0,0,0,22,0,0,0,7,129,35,145,65,200,
|
||||
4,73,6,16,50,57,146,1,132,12,37,5,8,25,30,4,139,98,128,16,69,2,66,146,11,66,132,16,50,20,56,8,24,75,10,50,66,136,72,112,196,33,35,68,18,135,140,16,65,146,2,100,200,8,177,20,32,67,70,
|
||||
136,32,201,1,50,66,132,24,42,40,42,144,49,124,176,92,145,32,196,200,0,0,0,137,32,0,0,24,0,0,0,50,34,8,9,32,98,70,0,33,43,36,152,16,33,37,36,152,16,25,39,12,133,164,144,96,66,100,92,
|
||||
32,36,100,130,224,153,1,24,70,32,128,97,4,1,184,67,72,32,37,77,17,37,76,62,149,82,210,193,57,141,52,1,205,148,4,145,65,4,66,48,197,136,68,145,13,4,204,17,128,129,10,228,28,1,40,12,
|
||||
34,8,194,48,2,145,140,0,0,0,0,0,81,24,0,0,100,0,0,0,27,246,35,248,255,255,255,255,1,48,5,192,15,0,56,0,254,0,144,0,10,232,3,34,28,224,1,30,228,225,29,240,161,13,204,161,30,220,97,28,
|
||||
218,192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,128,48,7,121,8,135,118,40,135,54,128,135,119,72,7,119,160,135,114,144,7,32,28,216,129,29,0,162,29,210,193,29,218,128,
|
||||
29,202,225,28,194,129,29,218,192,30,202,97,28,232,225,29,228,161,13,238,33,29,200,129,30,208,1,136,3,57,192,3,96,112,135,119,104,3,113,168,135,116,96,7,122,72,7,119,152,7,128,112,135,
|
||||
119,104,131,116,112,7,115,152,135,54,48,7,120,104,131,118,8,7,122,64,7,128,30,228,161,30,202,1,32,220,225,29,218,192,29,194,193,29,230,161,13,204,1,30,218,160,29,194,129,30,208,1,160,
|
||||
7,121,168,135,114,0,8,119,120,135,54,152,135,116,56,7,119,40,7,114,104,3,125,40,7,121,120,135,121,104,3,115,128,135,54,104,135,112,160,7,116,0,232,65,30,234,161,28,0,194,29,222,161,
|
||||
13,232,65,30,194,1,30,224,33,29,220,225,28,218,160,29,194,129,30,208,1,160,7,121,168,135,114,0,136,121,160,135,112,24,135,117,104,3,120,144,135,119,160,135,114,24,7,122,120,7,121,104,
|
||||
3,113,168,7,115,48,135,114,144,135,54,152,135,116,208,135,114,0,240,0,32,234,193,29,230,33,28,204,161,28,218,192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,96,195,24,8,
|
||||
4,176,0,164,0,84,65,128,4,105,0,13,225,144,14,242,208,6,226,80,15,230,96,14,229,32,15,109,224,14,239,208,6,225,192,14,233,16,14,243,0,0,0,73,24,0,0,1,0,0,0,19,132,64,0,19,170,112,72,
|
||||
7,121,176,3,58,104,131,112,128,7,120,96,135,114,104,131,116,120,135,121,136,3,60,112,131,56,112,3,56,216,112,27,229,208,6,240,160,7,118,64,7,122,96,7,116,160,7,118,64,7,109,144,14,
|
||||
113,160,7,120,160,7,120,208,6,233,128,7,122,128,7,122,128,7,109,144,14,113,96,7,122,16,7,118,160,7,113,96,7,109,144,14,115,32,7,122,48,7,114,160,7,115,32,7,109,144,14,118,64,7,122,
|
||||
96,7,116,160,7,118,64,7,109,96,14,115,32,7,122,48,7,114,160,7,115,32,7,109,96,14,118,64,7,122,96,7,116,160,7,118,64,7,109,96,15,113,96,7,122,16,7,118,160,7,113,96,7,109,96,15,114,64,
|
||||
7,122,48,7,114,160,7,115,32,7,109,96,15,115,32,7,122,48,7,114,160,7,115,32,7,109,96,15,116,128,7,122,96,7,116,160,7,118,64,7,109,96,15,118,64,7,122,96,7,116,160,7,118,64,7,109,96,15,
|
||||
121,96,7,122,16,7,114,128,7,122,16,7,114,128,7,109,96,15,113,32,7,120,160,7,113,32,7,120,160,7,113,32,7,120,208,6,246,16,7,121,32,7,122,32,7,117,96,7,122,32,7,117,96,7,109,96,15,114,
|
||||
80,7,118,160,7,114,80,7,118,160,7,114,80,7,118,208,6,246,80,7,113,32,7,122,80,7,113,32,7,122,80,7,113,32,7,109,96,15,113,0,7,114,64,7,122,16,7,112,32,7,116,160,7,113,0,7,114,64,7,109,
|
||||
224,14,120,160,7,113,96,7,122,48,7,114,160,17,194,144,5,3,32,13,61,164,2,10,3,0,128,0,0,0,64,0,0,0,0,0,160,0,36,54,8,20,85,26,0,0,200,2,1,0,11,0,0,0,50,30,152,16,25,17,76,144,140,9,
|
||||
38,71,198,4,67,202,34,40,129,66,40,135,242,41,64,129,130,40,144,17,128,50,160,29,1,32,29,75,144,2,0,0,0,0,177,24,0,0,165,0,0,0,51,8,128,28,196,225,28,102,20,1,61,136,67,56,132,195,
|
||||
140,66,128,7,121,120,7,115,152,113,12,230,0,15,237,16,14,244,128,14,51,12,66,30,194,193,29,206,161,28,102,48,5,61,136,67,56,132,131,27,204,3,61,200,67,61,140,3,61,204,120,140,116,112,
|
||||
7,123,8,7,121,72,135,112,112,7,122,112,3,118,120,135,112,32,135,25,204,17,14,236,144,14,225,48,15,110,48,15,227,240,14,240,80,14,51,16,196,29,222,33,28,216,33,29,194,97,30,102,48,137,
|
||||
59,188,131,59,208,67,57,180,3,60,188,131,60,132,3,59,204,240,20,118,96,7,123,104,7,55,104,135,114,104,7,55,128,135,112,144,135,112,96,7,118,40,7,118,248,5,118,120,135,119,128,135,95,
|
||||
8,135,113,24,135,114,152,135,121,152,129,44,238,240,14,238,224,14,245,192,14,236,48,3,98,200,161,28,228,161,28,204,161,28,228,161,28,220,97,28,202,33,28,196,129,29,202,97,6,214,144,
|
||||
67,57,200,67,57,152,67,57,200,67,57,184,195,56,148,67,56,136,3,59,148,195,47,188,131,60,252,130,59,212,3,59,176,195,12,199,105,135,112,88,135,114,112,131,116,104,7,120,96,135,116,24,
|
||||
135,116,160,135,25,206,83,15,238,0,15,242,80,14,228,144,14,227,64,15,225,32,14,236,80,14,51,32,40,29,220,193,30,194,65,30,210,33,28,220,129,30,220,224,28,228,225,29,234,1,30,102,24,
|
||||
81,56,176,67,58,156,131,59,204,80,36,118,96,7,123,104,7,55,96,135,119,120,7,120,152,81,76,244,144,15,240,80,14,51,30,106,30,202,97,28,232,33,29,222,193,29,126,1,30,228,161,28,204,33,
|
||||
29,240,97,6,84,133,131,56,204,195,59,176,67,61,208,67,57,252,194,60,228,67,59,136,195,59,176,195,140,197,10,135,121,152,135,119,24,135,116,8,7,122,40,7,114,152,129,92,227,16,14,236,
|
||||
192,14,229,80,14,243,48,35,193,210,65,30,228,225,23,216,225,29,222,1,30,102,72,25,59,176,131,61,180,131,27,132,195,56,140,67,57,204,195,60,184,193,57,200,195,59,212,3,60,204,72,180,
|
||||
113,8,7,118,96,7,113,8,135,113,88,135,25,219,198,14,236,96,15,237,224,6,240,32,15,229,48,15,229,32,15,246,80,14,110,16,14,227,48,14,229,48,15,243,224,6,233,224,14,228,80,14,248,48,
|
||||
35,226,236,97,28,194,129,29,216,225,23,236,33,29,230,33,29,196,33,29,216,33,29,232,33,31,102,32,157,59,188,67,61,184,3,57,148,131,57,204,88,188,112,112,7,119,120,7,122,8,7,122,72,135,
|
||||
119,112,135,25,206,135,14,229,16,14,240,16,14,236,192,14,239,48,14,243,144,14,244,80,14,51,40,48,8,135,116,144,7,55,48,135,122,112,135,113,160,135,116,120,7,119,248,133,115,144,135,
|
||||
119,168,7,120,152,7,0,0,0,0,121,32,0,0,25,1,0,0,114,30,72,32,67,136,12,25,9,114,50,72,32,35,129,140,145,145,209,68,160,16,40,100,60,49,50,66,142,144,33,163,152,6,100,208,82,0,0,0,139,
|
||||
210,88,216,6,109,80,28,20,27,71,6,209,18,25,76,178,24,6,179,64,18,49,24,202,131,68,148,161,68,87,35,0,0,0,0,83,68,75,32,86,101,114,115,105,111,110,119,99,104,97,114,95,115,105,122,
|
||||
101,102,114,97,109,101,45,112,111,105,110,116,101,114,97,105,114,46,109,97,120,95,100,101,118,105,99,101,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,99,111,110,115,116,
|
||||
97,110,116,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,104,114,101,97,100,103,114,111,117,112,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,101,120,
|
||||
116,117,114,101,115,97,105,114,46,109,97,120,95,114,101,97,100,95,119,114,105,116,101,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,115,97,109,112,108,101,114,115,
|
||||
65,112,112,108,101,32,109,101,116,97,108,32,118,101,114,115,105,111,110,32,51,50,48,50,51,46,51,54,56,32,40,109,101,116,97,108,102,101,45,51,50,48,50,51,46,51,54,56,41,77,101,116,97,
|
||||
108,97,105,114,46,99,111,109,112,105,108,101,46,100,101,110,111,114,109,115,95,100,105,115,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,97,115,116,95,109,97,116,104,
|
||||
95,101,110,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,114,97,109,101,98,117,102,102,101,114,95,102,101,116,99,104,95,101,110,97,98,108,101,97,105,114,46,118,101,
|
||||
114,116,101,120,95,111,117,116,112,117,116,117,115,101,114,40,108,111,99,110,48,41,97,105,114,46,97,114,103,95,116,121,112,101,95,110,97,109,101,102,108,111,97,116,52,97,105,114,46,
|
||||
97,114,103,95,110,97,109,101,79,117,116,95,67,111,108,111,114,117,115,101,114,40,108,111,99,110,49,41,102,108,111,97,116,50,79,117,116,95,85,86,97,105,114,46,112,111,115,105,116,105,
|
||||
111,110,103,108,95,80,111,115,105,116,105,111,110,97,105,114,46,118,101,114,116,101,120,95,105,110,112,117,116,97,105,114,46,108,111,99,97,116,105,111,110,95,105,110,100,101,120,97,
|
||||
80,111,115,97,85,86,97,67,111,108,111,114,97,105,114,46,98,117,102,102,101,114,97,105,114,46,98,117,102,102,101,114,95,115,105,122,101,97,105,114,46,114,101,97,100,97,105,114,46,97,
|
||||
100,100,114,101,115,115,95,115,112,97,99,101,97,105,114,46,115,116,114,117,99,116,95,116,121,112,101,95,105,110,102,111,117,83,99,97,108,101,117,84,114,97,110,115,108,97,116,101,97,
|
||||
105,114,46,97,114,103,95,116,121,112,101,95,115,105,122,101,97,105,114,46,97,114,103,95,116,121,112,101,95,97,108,105,103,110,95,115,105,122,101,117,80,117,115,104,67,111,110,115,116,
|
||||
97,110,116,112,99,0,0,0,230,117,0,0,0,0,0,0,48,130,144,4,35,8,10,51,130,144,8,35,8,201,48,130,144,16,35,8,73,49,130,144,24,35,8,201,49,130,144,32,35,8,73,50,130,144,40,35,8,7,48,195,
|
||||
160,6,193,26,204,48,176,129,208,6,51,12,110,48,168,193,12,131,27,16,111,48,195,224,6,197,27,204,48,184,129,241,6,51,12,110,112,192,193,12,131,27,32,113,48,195,224,6,137,28,204,16,40,
|
||||
51,12,106,224,6,115,48,3,177,208,129,26,204,193,12,1,51,67,208,204,16,56,51,24,15,20,73,19,53,131,241,84,145,53,93,51,20,88,36,77,217,12,67,41,152,194,41,204,144,204,129,182,205,1,
|
||||
27,68,214,196,205,144,176,129,182,177,1,27,68,214,212,205,144,168,129,182,169,1,27,68,210,228,205,160,204,65,28,204,129,69,6,113,16,7,115,96,149,193,12,20,29,124,96,32,7,219,28,176,
|
||||
65,24,136,129,26,140,1,43,152,129,28,156,65,28,68,104,48,165,193,12,68,42,168,194,42,180,194,12,67,29,160,130,43,156,25,0,28,199,113,28,199,113,28,199,113,110,224,6,110,224,6,110,224,
|
||||
6,110,224,6,110,96,209,129,30,88,150,69,7,116,224,6,116,128,11,184,128,11,252,128,30,160,32,35,129,9,202,136,141,205,174,205,165,237,141,172,142,173,204,197,140,45,236,108,110,148,
|
||||
164,14,236,224,14,240,32,15,244,96,15,248,160,15,82,97,99,179,107,115,73,35,43,115,163,27,37,240,131,92,194,210,228,92,236,202,228,230,210,222,220,70,9,254,32,169,176,52,57,23,182,
|
||||
48,183,179,186,176,179,178,47,187,50,185,185,180,55,183,81,2,80,200,41,44,77,206,101,236,173,13,46,141,173,236,235,13,142,46,237,205,109,110,148,33,20,68,97,20,82,9,75,147,115,177,
|
||||
43,147,163,43,195,27,37,112,5,0,0,0,169,24,0,0,37,0,0,0,11,10,114,40,135,119,128,7,122,88,112,152,67,61,184,195,56,176,67,57,208,195,130,230,28,198,161,13,232,65,30,194,193,29,230,
|
||||
33,29,232,33,29,222,193,29,22,52,227,96,14,231,80,15,225,32,15,228,64,15,225,32,15,231,80,14,244,176,128,129,7,121,40,135,112,96,7,118,120,135,113,8,7,122,40,7,114,88,112,156,195,56,
|
||||
180,1,59,164,131,61,148,195,2,107,28,216,33,28,220,225,28,220,32,28,228,97,28,220,32,28,232,129,30,194,97,28,208,161,28,200,97,28,194,129,29,216,97,193,1,15,244,32,15,225,80,15,244,
|
||||
128,14,0,0,0,0,209,16,0,0,6,0,0,0,7,204,60,164,131,59,156,3,59,148,3,61,160,131,60,148,67,56,144,195,1,0,0,0,97,32,0,0,68,0,0,0,19,4,65,44,16,0,0,0,11,0,0,0,148,51,0,197,64,91,2,212,
|
||||
115,16,73,20,69,115,16,73,36,17,4,163,1,35,0,99,4,32,8,130,248,71,49,7,97,89,23,70,50,26,64,51,3,0,0,0,241,48,0,0,32,0,0,0,34,71,200,144,81,18,196,43,0,0,0,0,207,115,89,0,111,109,110,
|
||||
105,112,111,116,101,110,116,32,99,104,97,114,83,105,109,112,108,101,32,67,43,43,32,84,66,65,65,97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,115,40,109,97,105,110,48,41,97,
|
||||
105,114,45,97,108,105,97,115,45,115,99,111,112,101,45,97,114,103,40,51,41,0,19,132,101,89,33,212,130,44,172,24,108,161,22,102,97,67,16,11,27,6,88,184,5,90,216,48,224,2,46,208,194,134,
|
||||
192,22,0,0,157,6,38,154,40,16,130,65,36,254,157,134,135,234,40,16,130,67,0,254,131,12,1,226,12,50,4,138,51,134,48,68,22,128,255,28,195,16,76,179,13,12,6,204,54,4,90,48,219,16,12,194,
|
||||
6,1,49,0,4,0,0,0,91,138,32,192,133,35,23,182,20,68,128,11,71,46,0,0,0,0,0,0,113,32,0,0,3,0,0,0,50,14,16,34,132,0,132,6,0,0,0,0,0,0,0,0,101,12,0,0,31,0,0,0,18,3,148,240,0,0,0,0,3,0,
|
||||
0,0,5,0,0,0,9,0,0,0,76,0,0,0,1,0,0,0,88,0,0,0,0,0,0,0,88,0,0,0,1,0,0,0,112,0,0,0,0,0,0,0,14,0,0,0,21,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0,0,0,0,0,112,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,
|
||||
0,0,0,0,5,0,0,0,0,0,0,0,5,0,0,0,255,255,255,255,0,36,0,0,0,0,0,0,93,12,0,0,12,0,0,0,18,3,148,99,0,0,0,0,109,97,105,110,48,51,50,48,50,51,46,51,54,56,97,105,114,54,52,45,97,112,112,
|
||||
108,101,45,105,111,115,49,56,46,49,46,48,0,0,0,0,0,
|
||||
};
|
||||
const uint8_t metallib_fragment[3771] = {
|
||||
77,84,76,66,1,0,2,0,7,0,0,130,18,0,1,0,187,14,0,0,0,0,0,0,88,0,0,0,0,0,0,0,123,0,0,0,0,0,0,0,219,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,227,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,235,0,0,0,0,0,0,0,208,
|
||||
13,0,0,0,0,0,0,1,0,0,0,123,0,0,0,78,65,77,69,6,0,109,97,105,110,48,0,84,89,80,69,1,0,1,72,65,83,72,32,0,167,26,51,31,140,153,203,226,66,149,243,47,185,58,96,202,28,176,71,121,86,159,
|
||||
244,234,235,69,155,58,121,67,241,212,77,68,83,90,8,0,208,13,0,0,0,0,0,0,79,70,70,84,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,69,82,83,8,0,2,0,7,0,3,0,2,0,69,78,68,84,
|
||||
69,78,68,84,4,0,0,0,69,78,68,84,4,0,0,0,69,78,68,84,222,192,23,11,0,0,0,0,20,0,0,0,180,13,0,0,255,255,255,255,66,67,192,222,53,20,0,0,3,0,0,0,98,12,48,36,128,16,5,200,20,0,0,0,33,12,
|
||||
0,0,41,3,0,0,11,2,33,0,2,0,0,0,22,0,0,0,7,129,35,145,65,200,4,73,6,16,50,57,146,1,132,12,37,5,8,25,30,4,139,98,128,20,69,2,66,146,11,66,164,16,50,20,56,8,24,75,10,50,82,136,72,112,
|
||||
196,33,35,68,18,135,140,16,65,146,2,100,200,8,177,20,32,67,70,136,32,201,1,50,82,132,24,42,40,42,144,49,124,176,92,145,32,197,200,0,0,0,137,32,0,0,31,0,0,0,50,34,72,9,32,98,70,0,33,
|
||||
43,36,152,20,33,37,36,152,20,25,39,12,133,164,144,96,82,100,92,32,36,101,130,128,154,1,24,70,32,128,27,132,97,4,1,64,74,154,34,74,152,252,127,34,174,137,138,136,223,30,254,105,140,
|
||||
0,24,68,32,2,140,164,41,162,132,201,255,37,128,121,22,34,250,167,49,2,96,16,193,16,76,33,194,40,135,208,28,1,114,132,160,230,8,130,57,2,48,24,70,16,26,163,172,114,6,115,12,128,70,111,
|
||||
32,64,5,218,8,0,0,81,24,0,0,105,0,0,0,27,246,35,248,255,255,255,255,1,104,3,96,13,0,83,0,252,0,144,128,10,232,3,34,28,224,1,30,228,225,29,240,161,13,204,161,30,220,97,28,218,192,28,
|
||||
224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,128,48,7,121,8,135,118,40,135,54,128,135,119,72,7,119,160,135,114,144,7,32,28,216,129,29,0,162,29,210,193,29,218,128,29,202,225,
|
||||
28,194,129,29,218,192,30,202,97,28,232,225,29,228,161,13,238,33,29,200,129,30,208,1,136,3,57,192,3,96,112,135,119,104,3,113,168,135,116,96,7,122,72,7,119,152,7,128,112,135,119,104,
|
||||
131,116,112,7,115,152,135,54,48,7,120,104,131,118,8,7,122,64,7,128,30,228,161,30,202,1,32,220,225,29,218,192,29,194,193,29,230,161,13,204,1,30,218,160,29,194,129,30,208,1,160,7,121,
|
||||
168,135,114,0,8,119,120,135,54,152,135,116,56,7,119,40,7,114,104,3,125,40,7,121,120,135,121,104,3,115,128,135,54,104,135,112,160,7,116,0,232,65,30,234,161,28,0,194,29,222,161,13,232,
|
||||
65,30,194,1,30,224,33,29,220,225,28,218,160,29,194,129,30,208,1,160,7,121,168,135,114,0,136,121,160,135,112,24,135,117,104,3,120,144,135,119,160,135,114,24,7,122,120,7,121,104,3,113,
|
||||
168,7,115,48,135,114,144,135,54,152,135,116,208,135,114,0,240,0,32,234,193,29,230,33,28,204,161,28,218,192,28,224,161,13,218,33,28,232,1,29,0,122,144,135,122,40,7,96,131,33,12,192,
|
||||
2,84,27,140,129,0,22,160,218,0,17,255,255,255,255,63,0,109,0,172,1,96,10,128,31,0,18,80,1,125,176,193,40,2,96,1,170,13,134,33,0,11,80,109,96,142,255,255,255,255,31,128,54,0,214,0,144,
|
||||
128,10,232,3,0,73,24,0,0,4,0,0,0,19,134,64,24,38,12,68,97,76,24,142,194,0,0,0,0,19,170,112,72,7,121,176,3,58,104,131,112,128,7,120,96,135,114,104,131,116,120,135,121,136,3,60,112,131,
|
||||
56,112,3,56,216,112,27,229,208,6,240,160,7,118,64,7,122,96,7,116,160,7,118,64,7,109,144,14,113,160,7,120,160,7,120,208,6,233,128,7,122,128,7,122,128,7,109,144,14,113,96,7,122,16,7,
|
||||
118,160,7,113,96,7,109,144,14,115,32,7,122,48,7,114,160,7,115,32,7,109,144,14,118,64,7,122,96,7,116,160,7,118,64,7,109,96,14,115,32,7,122,48,7,114,160,7,115,32,7,109,96,14,118,64,7,
|
||||
122,96,7,116,160,7,118,64,7,109,96,15,113,96,7,122,16,7,118,160,7,113,96,7,109,96,15,114,64,7,122,48,7,114,160,7,115,32,7,109,96,15,115,32,7,122,48,7,114,160,7,115,32,7,109,96,15,116,
|
||||
128,7,122,96,7,116,160,7,118,64,7,109,96,15,118,64,7,122,96,7,116,160,7,118,64,7,109,96,15,121,96,7,122,16,7,114,128,7,122,16,7,114,128,7,109,96,15,113,32,7,120,160,7,113,32,7,120,
|
||||
160,7,113,32,7,120,208,6,246,16,7,121,32,7,122,32,7,117,96,7,122,32,7,117,96,7,109,96,15,114,80,7,118,160,7,114,80,7,118,160,7,114,80,7,118,208,6,246,80,7,113,32,7,122,80,7,113,32,
|
||||
7,122,80,7,113,32,7,109,96,15,113,0,7,114,64,7,122,16,7,112,32,7,116,160,7,113,0,7,114,64,7,109,224,14,120,160,7,113,96,7,122,48,7,114,160,17,194,144,5,3,32,13,61,164,2,10,4,0,128,
|
||||
0,0,0,64,0,0,0,0,0,160,0,134,84,197,246,0,1,32,0,0,0,8,0,0,0,0,0,20,128,196,6,129,162,43,3,0,0,89,32,10,0,0,0,50,30,152,16,25,17,76,144,140,9,38,71,198,4,67,106,69,80,2,133,80,14,229,
|
||||
83,128,2,5,81,32,35,0,101,64,114,44,65,10,0,0,0,177,24,0,0,165,0,0,0,51,8,128,28,196,225,28,102,20,1,61,136,67,56,132,195,140,66,128,7,121,120,7,115,152,113,12,230,0,15,237,16,14,244,
|
||||
128,14,51,12,66,30,194,193,29,206,161,28,102,48,5,61,136,67,56,132,131,27,204,3,61,200,67,61,140,3,61,204,120,140,116,112,7,123,8,7,121,72,135,112,112,7,122,112,3,118,120,135,112,32,
|
||||
135,25,204,17,14,236,144,14,225,48,15,110,48,15,227,240,14,240,80,14,51,16,196,29,222,33,28,216,33,29,194,97,30,102,48,137,59,188,131,59,208,67,57,180,3,60,188,131,60,132,3,59,204,
|
||||
240,20,118,96,7,123,104,7,55,104,135,114,104,7,55,128,135,112,144,135,112,96,7,118,40,7,118,248,5,118,120,135,119,128,135,95,8,135,113,24,135,114,152,135,121,152,129,44,238,240,14,
|
||||
238,224,14,245,192,14,236,48,3,98,200,161,28,228,161,28,204,161,28,228,161,28,220,97,28,202,33,28,196,129,29,202,97,6,214,144,67,57,200,67,57,152,67,57,200,67,57,184,195,56,148,67,
|
||||
56,136,3,59,148,195,47,188,131,60,252,130,59,212,3,59,176,195,12,199,105,135,112,88,135,114,112,131,116,104,7,120,96,135,116,24,135,116,160,135,25,206,83,15,238,0,15,242,80,14,228,
|
||||
144,14,227,64,15,225,32,14,236,80,14,51,32,40,29,220,193,30,194,65,30,210,33,28,220,129,30,220,224,28,228,225,29,234,1,30,102,24,81,56,176,67,58,156,131,59,204,80,36,118,96,7,123,104,
|
||||
7,55,96,135,119,120,7,120,152,81,76,244,144,15,240,80,14,51,30,106,30,202,97,28,232,33,29,222,193,29,126,1,30,228,161,28,204,33,29,240,97,6,84,133,131,56,204,195,59,176,67,61,208,67,
|
||||
57,252,194,60,228,67,59,136,195,59,176,195,140,197,10,135,121,152,135,119,24,135,116,8,7,122,40,7,114,152,129,92,227,16,14,236,192,14,229,80,14,243,48,35,193,210,65,30,228,225,23,216,
|
||||
225,29,222,1,30,102,72,25,59,176,131,61,180,131,27,132,195,56,140,67,57,204,195,60,184,193,57,200,195,59,212,3,60,204,72,180,113,8,7,118,96,7,113,8,135,113,88,135,25,219,198,14,236,
|
||||
96,15,237,224,6,240,32,15,229,48,15,229,32,15,246,80,14,110,16,14,227,48,14,229,48,15,243,224,6,233,224,14,228,80,14,248,48,35,226,236,97,28,194,129,29,216,225,23,236,33,29,230,33,
|
||||
29,196,33,29,216,33,29,232,33,31,102,32,157,59,188,67,61,184,3,57,148,131,57,204,88,188,112,112,7,119,120,7,122,8,7,122,72,135,119,112,135,25,206,135,14,229,16,14,240,16,14,236,192,
|
||||
14,239,48,14,243,144,14,244,80,14,51,40,48,8,135,116,144,7,55,48,135,122,112,135,113,160,135,116,120,7,119,248,133,115,144,135,119,168,7,120,152,7,0,0,0,0,121,32,0,0,251,0,0,0,114,
|
||||
30,72,32,67,136,12,25,9,114,50,72,32,35,129,140,145,145,209,68,160,16,40,100,60,49,50,66,142,144,33,163,56,6,220,41,1,0,0,0,139,210,88,216,6,109,80,28,20,27,71,6,81,100,48,134,180,
|
||||
40,15,178,24,197,34,41,24,178,28,13,83,68,75,32,86,101,114,115,105,111,110,119,99,104,97,114,95,115,105,122,101,102,114,97,109,101,45,112,111,105,110,116,101,114,97,105,114,46,109,
|
||||
97,120,95,100,101,118,105,99,101,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,99,111,110,115,116,97,110,116,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,
|
||||
104,114,101,97,100,103,114,111,117,112,95,98,117,102,102,101,114,115,97,105,114,46,109,97,120,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,114,101,97,100,95,119,114,
|
||||
105,116,101,95,116,101,120,116,117,114,101,115,97,105,114,46,109,97,120,95,115,97,109,112,108,101,114,115,65,112,112,108,101,32,109,101,116,97,108,32,118,101,114,115,105,111,110,32,
|
||||
51,50,48,50,51,46,51,54,56,32,40,109,101,116,97,108,102,101,45,51,50,48,50,51,46,51,54,56,41,77,101,116,97,108,97,105,114,46,99,111,109,112,105,108,101,46,100,101,110,111,114,109,115,
|
||||
95,100,105,115,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,97,115,116,95,109,97,116,104,95,101,110,97,98,108,101,97,105,114,46,99,111,109,112,105,108,101,46,102,114,
|
||||
97,109,101,98,117,102,102,101,114,95,102,101,116,99,104,95,101,110,97,98,108,101,97,105,114,46,114,101,110,100,101,114,95,116,97,114,103,101,116,97,105,114,46,97,114,103,95,116,121,
|
||||
112,101,95,110,97,109,101,102,108,111,97,116,52,97,105,114,46,97,114,103,95,110,97,109,101,102,67,111,108,111,114,97,105,114,46,102,114,97,103,109,101,110,116,95,105,110,112,117,116,
|
||||
117,115,101,114,40,108,111,99,110,48,41,97,105,114,46,99,101,110,116,101,114,97,105,114,46,112,101,114,115,112,101,99,116,105,118,101,73,110,95,67,111,108,111,114,117,115,101,114,40,
|
||||
108,111,99,110,49,41,102,108,111,97,116,50,73,110,95,85,86,97,105,114,46,116,101,120,116,117,114,101,97,105,114,46,108,111,99,97,116,105,111,110,95,105,110,100,101,120,97,105,114,46,
|
||||
115,97,109,112,108,101,116,101,120,116,117,114,101,50,100,60,102,108,111,97,116,44,32,115,97,109,112,108,101,62,115,84,101,120,116,117,114,101,97,105,114,46,115,97,109,112,108,101,
|
||||
114,115,97,109,112,108,101,114,115,84,101,120,116,117,114,101,83,109,112,108,114,0,6,95,0,0,0,0,0,0,48,130,208,8,35,8,18,51,130,208,12,35,8,13,49,130,208,20,35,8,141,49,130,208,28,
|
||||
35,8,13,50,130,208,36,35,8,141,50,130,208,44,35,8,9,48,195,64,6,65,25,204,48,152,129,112,6,51,12,104,48,144,193,12,3,26,16,105,48,195,128,6,69,26,204,48,160,129,145,6,51,12,104,112,
|
||||
168,193,12,3,26,32,107,48,195,128,6,9,27,204,16,40,51,12,100,128,6,109,48,3,177,184,1,25,180,193,12,1,51,67,208,204,16,56,51,28,79,27,180,1,20,73,211,12,193,31,204,144,180,1,85,89,
|
||||
23,20,73,216,12,137,25,80,153,117,65,154,180,205,160,144,1,215,181,129,25,120,208,39,129,193,12,137,27,132,65,215,6,102,0,137,129,52,6,51,16,161,32,10,163,64,10,51,12,111,0,10,165,
|
||||
112,99,0,112,28,199,113,28,199,113,28,199,185,129,27,184,129,27,184,129,27,184,129,27,184,129,69,7,122,96,89,150,41,112,172,192,10,228,160,14,160,32,35,129,9,202,136,141,205,174,205,
|
||||
165,237,141,172,142,173,204,197,140,45,236,108,110,148,228,13,224,32,14,228,96,14,232,160,14,236,224,14,82,97,99,179,107,115,73,35,43,115,163,27,37,192,131,92,194,210,228,92,236,202,
|
||||
228,230,210,222,220,70,9,242,32,169,176,52,57,23,182,48,183,179,186,176,179,178,47,187,50,185,185,180,55,183,81,2,61,200,41,44,77,206,101,236,173,13,46,141,173,236,235,13,142,46,237,
|
||||
205,109,110,148,97,15,248,160,15,146,9,75,147,115,49,147,11,59,107,43,115,163,27,37,40,5,0,0,0,0,169,24,0,0,37,0,0,0,11,10,114,40,135,119,128,7,122,88,112,152,67,61,184,195,56,176,
|
||||
67,57,208,195,130,230,28,198,161,13,232,65,30,194,193,29,230,33,29,232,33,29,222,193,29,22,52,227,96,14,231,80,15,225,32,15,228,64,15,225,32,15,231,80,14,244,176,128,129,7,121,40,135,
|
||||
112,96,7,118,120,135,113,8,7,122,40,7,114,88,112,156,195,56,180,1,59,164,131,61,148,195,2,107,28,216,33,28,220,225,28,220,32,28,228,97,28,220,32,28,232,129,30,194,97,28,208,161,28,
|
||||
200,97,28,194,129,29,216,97,193,1,15,244,32,15,225,80,15,244,128,14,0,0,0,0,209,16,0,0,6,0,0,0,7,204,60,164,131,59,156,3,59,148,3,61,160,131,60,148,67,56,144,195,1,0,0,0,97,32,0,0,
|
||||
49,0,0,0,19,4,65,44,16,0,0,0,4,0,0,0,196,106,96,4,128,220,8,0,129,17,0,18,51,0,0,0,241,48,0,0,28,0,0,0,34,71,200,144,81,14,196,42,0,0,0,0,23,134,1,0,97,105,114,45,97,108,105,97,115,
|
||||
45,115,99,111,112,101,115,40,109,97,105,110,48,41,97,105,114,45,97,108,105,97,115,45,115,99,111,112,101,45,115,97,109,112,108,101,114,115,97,105,114,45,97,108,105,97,115,45,115,99,
|
||||
111,112,101,45,116,101,120,116,117,114,101,115,0,43,4,85,56,133,21,195,42,168,2,42,172,24,88,65,21,82,97,131,192,10,171,0,0,35,6,205,16,130,96,240,84,135,129,20,3,33,8,204,104,66,0,
|
||||
96,176,136,255,108,3,17,0,27,4,196,0,0,0,2,0,0,0,91,6,224,96,5,0,0,0,0,0,0,0,113,32,0,0,3,0,0,0,50,14,16,34,132,0,248,5,0,0,0,0,0,0,0,0,101,12,0,0,37,0,0,0,18,3,148,40,1,0,0,0,3,0,
|
||||
0,0,32,0,0,0,9,0,0,0,76,0,0,0,1,0,0,0,88,0,0,0,0,0,0,0,88,0,0,0,2,0,0,0,136,0,0,0,0,0,0,0,41,0,0,0,21,0,0,0,0,0,0,0,5,0,0,0,5,0,0,0,0,0,0,0,136,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,
|
||||
0,0,0,0,0,5,0,0,0,0,0,0,0,5,0,0,0,255,255,255,255,0,36,0,0,5,0,0,0,27,0,0,0,5,0,0,0,27,0,0,0,255,255,255,255,8,36,0,0,0,0,0,0,93,12,0,0,19,0,0,0,18,3,148,126,0,0,0,0,109,97,105,110,
|
||||
48,97,105,114,46,115,97,109,112,108,101,95,116,101,120,116,117,114,101,95,50,100,46,118,52,102,51,50,51,50,48,50,51,46,51,54,56,97,105,114,54,52,45,97,112,112,108,101,45,105,111,115,
|
||||
49,56,46,49,46,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
};
|
||||
#elif TARGET_IPHONE_SIMULATOR
|
||||
#error "SDL_GPU does not support the iphone simulator"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
+280
@@ -0,0 +1,280 @@
|
||||
// dear imgui: Renderer Backend for SDL_Renderer for SDL2
|
||||
// (Requires: SDL 2.0.17+)
|
||||
|
||||
// Note that SDL_Renderer is an _optional_ component of SDL2, which IMHO is now largely obsolete.
|
||||
// For a multi-platform app consider using other technologies:
|
||||
// - SDL3+SDL_GPU: SDL_GPU is SDL3 new graphics abstraction API. You will need to update to SDL3.
|
||||
// - SDL2+DirectX, SDL2+OpenGL, SDL2+Vulkan: combine SDL with dedicated renderers.
|
||||
// If your application wants to render any non trivial amount of graphics other than UI,
|
||||
// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user
|
||||
// and it might be difficult to step out of those boundaries.
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
||||
|
||||
// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// CHANGELOG
|
||||
// 2025-01-18: Use endian-dependent RGBA32 texture format, to match SDL_Color.
|
||||
// 2024-10-09: Expose selected render state in ImGui_ImplSDLRenderer2_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||
// 2024-05-14: *BREAKING CHANGE* ImGui_ImplSDLRenderer3_RenderDrawData() requires SDL_Renderer* passed as parameter.
|
||||
// 2023-05-30: Renamed imgui_impl_sdlrenderer.h/.cpp to imgui_impl_sdlrenderer2.h/.cpp to accommodate for upcoming SDL3.
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-12-21: Update SDL_RenderGeometryRaw() format to work with SDL 2.0.19.
|
||||
// 2021-12-03: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
|
||||
// 2021-10-06: Backup and restore modified ClipRect/Viewport.
|
||||
// 2021-09-21: Initial version.
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_sdlrenderer2.h"
|
||||
#include <stdint.h> // intptr_t
|
||||
|
||||
// Clang warnings with -Weverything
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||
#endif
|
||||
|
||||
// SDL
|
||||
#include <SDL.h>
|
||||
#if !SDL_VERSION_ATLEAST(2,0,17)
|
||||
#error This backend requires SDL 2.0.17+ because of SDL_RenderGeometry() function
|
||||
#endif
|
||||
|
||||
// SDL_Renderer data
|
||||
struct ImGui_ImplSDLRenderer2_Data
|
||||
{
|
||||
SDL_Renderer* Renderer; // Main viewport's renderer
|
||||
SDL_Texture* FontTexture;
|
||||
ImGui_ImplSDLRenderer2_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||
static ImGui_ImplSDLRenderer2_Data* ImGui_ImplSDLRenderer2_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLRenderer2_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
// Functions
|
||||
bool ImGui_ImplSDLRenderer2_Init(SDL_Renderer* renderer)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
IM_ASSERT(renderer != nullptr && "SDL_Renderer not initialized!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplSDLRenderer2_Data* bd = IM_NEW(ImGui_ImplSDLRenderer2_Data)();
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_sdlrenderer2";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
|
||||
bd->Renderer = renderer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLRenderer2_Shutdown()
|
||||
{
|
||||
ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplSDLRenderer2_DestroyDeviceObjects();
|
||||
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLRenderer2_SetupRenderState(SDL_Renderer* renderer)
|
||||
{
|
||||
// Clear out any viewports and cliprect set by the user
|
||||
// FIXME: Technically speaking there are lots of other things we could backup/setup/restore during our render process.
|
||||
SDL_RenderSetViewport(renderer, nullptr);
|
||||
SDL_RenderSetClipRect(renderer, nullptr);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLRenderer2_NewFrame()
|
||||
{
|
||||
ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDLRenderer2_Init()?");
|
||||
|
||||
if (!bd->FontTexture)
|
||||
ImGui_ImplSDLRenderer2_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer)
|
||||
{
|
||||
// If there's a scale factor set by the user, use that instead
|
||||
// If the user has specified a scale factor to SDL_Renderer already via SDL_RenderSetScale(), SDL will scale whatever we pass
|
||||
// to SDL_RenderGeometryRaw() by that scale factor. In that case we don't want to be also scaling it ourselves here.
|
||||
float rsx = 1.0f;
|
||||
float rsy = 1.0f;
|
||||
SDL_RenderGetScale(renderer, &rsx, &rsy);
|
||||
ImVec2 render_scale;
|
||||
render_scale.x = (rsx == 1.0f) ? draw_data->FramebufferScale.x : 1.0f;
|
||||
render_scale.y = (rsy == 1.0f) ? draw_data->FramebufferScale.y : 1.0f;
|
||||
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * render_scale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * render_scale.y);
|
||||
if (fb_width == 0 || fb_height == 0)
|
||||
return;
|
||||
|
||||
// Backup SDL_Renderer state that will be modified to restore it afterwards
|
||||
struct BackupSDLRendererState
|
||||
{
|
||||
SDL_Rect Viewport;
|
||||
bool ClipEnabled;
|
||||
SDL_Rect ClipRect;
|
||||
};
|
||||
BackupSDLRendererState old = {};
|
||||
old.ClipEnabled = SDL_RenderIsClipEnabled(renderer) == SDL_TRUE;
|
||||
SDL_RenderGetViewport(renderer, &old.Viewport);
|
||||
SDL_RenderGetClipRect(renderer, &old.ClipRect);
|
||||
|
||||
// Setup desired state
|
||||
ImGui_ImplSDLRenderer2_SetupRenderState(renderer);
|
||||
|
||||
// Setup render state structure (for callbacks and custom texture bindings)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
ImGui_ImplSDLRenderer2_RenderState render_state;
|
||||
render_state.Renderer = renderer;
|
||||
platform_io.Renderer_RenderState = &render_state;
|
||||
|
||||
// Will project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||
ImVec2 clip_scale = render_scale;
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
|
||||
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplSDLRenderer2_SetupRenderState(renderer);
|
||||
else
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||
if (clip_min.x < 0.0f) { clip_min.x = 0.0f; }
|
||||
if (clip_min.y < 0.0f) { clip_min.y = 0.0f; }
|
||||
if (clip_max.x > (float)fb_width) { clip_max.x = (float)fb_width; }
|
||||
if (clip_max.y > (float)fb_height) { clip_max.y = (float)fb_height; }
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
SDL_Rect r = { (int)(clip_min.x), (int)(clip_min.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y) };
|
||||
SDL_RenderSetClipRect(renderer, &r);
|
||||
|
||||
const float* xy = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, pos));
|
||||
const float* uv = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, uv));
|
||||
#if SDL_VERSION_ATLEAST(2,0,19)
|
||||
const SDL_Color* color = (const SDL_Color*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col)); // SDL 2.0.19+
|
||||
#else
|
||||
const int* color = (const int*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col)); // SDL 2.0.17 and 2.0.18
|
||||
#endif
|
||||
|
||||
// Bind texture, Draw
|
||||
SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
|
||||
SDL_RenderGeometryRaw(renderer, tex,
|
||||
xy, (int)sizeof(ImDrawVert),
|
||||
color, (int)sizeof(ImDrawVert),
|
||||
uv, (int)sizeof(ImDrawVert),
|
||||
draw_list->VtxBuffer.Size - pcmd->VtxOffset,
|
||||
idx_buffer + pcmd->IdxOffset, pcmd->ElemCount, sizeof(ImDrawIdx));
|
||||
}
|
||||
}
|
||||
}
|
||||
platform_io.Renderer_RenderState = nullptr;
|
||||
|
||||
// Restore modified SDL_Renderer state
|
||||
SDL_RenderSetViewport(renderer, &old.Viewport);
|
||||
SDL_RenderSetClipRect(renderer, old.ClipEnabled ? &old.ClipRect : nullptr);
|
||||
}
|
||||
|
||||
// Called by Init/NewFrame/Shutdown
|
||||
bool ImGui_ImplSDLRenderer2_CreateFontsTexture()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();
|
||||
|
||||
// Build texture atlas
|
||||
unsigned char* pixels;
|
||||
int width, height;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
|
||||
|
||||
// Upload texture to graphics system
|
||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||
bd->FontTexture = SDL_CreateTexture(bd->Renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, width, height);
|
||||
if (bd->FontTexture == nullptr)
|
||||
{
|
||||
SDL_Log("error creating texture");
|
||||
return false;
|
||||
}
|
||||
SDL_UpdateTexture(bd->FontTexture, nullptr, pixels, 4 * width);
|
||||
SDL_SetTextureBlendMode(bd->FontTexture, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetTextureScaleMode(bd->FontTexture, SDL_ScaleModeLinear);
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLRenderer2_DestroyFontsTexture()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();
|
||||
if (bd->FontTexture)
|
||||
{
|
||||
io.Fonts->SetTexID(0);
|
||||
SDL_DestroyTexture(bd->FontTexture);
|
||||
bd->FontTexture = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDLRenderer2_CreateDeviceObjects()
|
||||
{
|
||||
return ImGui_ImplSDLRenderer2_CreateFontsTexture();
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLRenderer2_DestroyDeviceObjects()
|
||||
{
|
||||
ImGui_ImplSDLRenderer2_DestroyFontsTexture();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
@@ -0,0 +1,53 @@
|
||||
// dear imgui: Renderer Backend for SDL_Renderer for SDL2
|
||||
// (Requires: SDL 2.0.17+)
|
||||
|
||||
// Note that SDL_Renderer is an _optional_ component of SDL2, which IMHO is now largely obsolete.
|
||||
// For a multi-platform app consider using other technologies:
|
||||
// - SDL3+SDL_GPU: SDL_GPU is SDL3 new graphics abstraction API. You will need to update to SDL3.
|
||||
// - SDL2+DirectX, SDL2+OpenGL, SDL2+Vulkan: combine SDL with dedicated renderers.
|
||||
// If your application wants to render any non trivial amount of graphics other than UI,
|
||||
// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user
|
||||
// and it might be difficult to step out of those boundaries.
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#pragma once
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
|
||||
struct SDL_Renderer;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer2_Init(SDL_Renderer* renderer);
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer);
|
||||
|
||||
// Called by Init/NewFrame/Shutdown
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer2_CreateFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_DestroyFontsTexture();
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer2_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_DestroyDeviceObjects();
|
||||
|
||||
// [BETA] Selected render state data shared with callbacks.
|
||||
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplSDLRenderer2_RenderDrawData() call.
|
||||
// (Please open an issue if you feel you need access to more data)
|
||||
struct ImGui_ImplSDLRenderer2_RenderState
|
||||
{
|
||||
SDL_Renderer* Renderer;
|
||||
};
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
+297
@@ -0,0 +1,297 @@
|
||||
// dear imgui: Renderer Backend for SDL_Renderer for SDL3
|
||||
// (Requires: SDL 3.1.8+)
|
||||
|
||||
// Note that SDL_Renderer is an _optional_ component of SDL3, which IMHO is now largely obsolete.
|
||||
// For a multi-platform app consider using other technologies:
|
||||
// - SDL3+SDL_GPU: SDL_GPU is SDL3 new graphics abstraction API.
|
||||
// - SDL3+DirectX, SDL3+OpenGL, SDL3+Vulkan: combine SDL with dedicated renderers.
|
||||
// If your application wants to render any non trivial amount of graphics other than UI,
|
||||
// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user
|
||||
// and it might be difficult to step out of those boundaries.
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
||||
|
||||
// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// CHANGELOG
|
||||
// 2025-01-18: Use endian-dependent RGBA32 texture format, to match SDL_Color.
|
||||
// 2024-10-09: Expose selected render state in ImGui_ImplSDLRenderer3_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||
// 2024-07-01: Update for SDL3 api changes: SDL_RenderGeometryRaw() uint32 version was removed (SDL#9009).
|
||||
// 2024-05-14: *BREAKING CHANGE* ImGui_ImplSDLRenderer3_RenderDrawData() requires SDL_Renderer* passed as parameter.
|
||||
// 2024-02-12: Amend to query SDL_RenderViewportSet() and restore viewport accordingly.
|
||||
// 2023-05-30: Initial version.
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_sdlrenderer3.h"
|
||||
#include <stdint.h> // intptr_t
|
||||
|
||||
// Clang warnings with -Weverything
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||
#endif
|
||||
|
||||
// SDL
|
||||
#include <SDL3/SDL.h>
|
||||
#if !SDL_VERSION_ATLEAST(3,0,0)
|
||||
#error This backend requires SDL 3.0.0+
|
||||
#endif
|
||||
|
||||
// SDL_Renderer data
|
||||
struct ImGui_ImplSDLRenderer3_Data
|
||||
{
|
||||
SDL_Renderer* Renderer; // Main viewport's renderer
|
||||
SDL_Texture* FontTexture;
|
||||
ImVector<SDL_FColor> ColorBuffer;
|
||||
|
||||
ImGui_ImplSDLRenderer3_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||
static ImGui_ImplSDLRenderer3_Data* ImGui_ImplSDLRenderer3_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLRenderer3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
// Functions
|
||||
bool ImGui_ImplSDLRenderer3_Init(SDL_Renderer* renderer)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
IM_ASSERT(renderer != nullptr && "SDL_Renderer not initialized!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplSDLRenderer3_Data* bd = IM_NEW(ImGui_ImplSDLRenderer3_Data)();
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_sdlrenderer3";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
|
||||
bd->Renderer = renderer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLRenderer3_Shutdown()
|
||||
{
|
||||
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplSDLRenderer3_DestroyDeviceObjects();
|
||||
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLRenderer3_SetupRenderState(SDL_Renderer* renderer)
|
||||
{
|
||||
// Clear out any viewports and cliprect set by the user
|
||||
// FIXME: Technically speaking there are lots of other things we could backup/setup/restore during our render process.
|
||||
SDL_SetRenderViewport(renderer, nullptr);
|
||||
SDL_SetRenderClipRect(renderer, nullptr);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLRenderer3_NewFrame()
|
||||
{
|
||||
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDLRenderer3_Init()?");
|
||||
|
||||
if (!bd->FontTexture)
|
||||
ImGui_ImplSDLRenderer3_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
// https://github.com/libsdl-org/SDL/issues/9009
|
||||
static int SDL_RenderGeometryRaw8BitColor(SDL_Renderer* renderer, ImVector<SDL_FColor>& colors_out, SDL_Texture* texture, const float* xy, int xy_stride, const SDL_Color* color, int color_stride, const float* uv, int uv_stride, int num_vertices, const void* indices, int num_indices, int size_indices)
|
||||
{
|
||||
const Uint8* color2 = (const Uint8*)color;
|
||||
colors_out.resize(num_vertices);
|
||||
SDL_FColor* color3 = colors_out.Data;
|
||||
for (int i = 0; i < num_vertices; i++)
|
||||
{
|
||||
color3[i].r = color->r / 255.0f;
|
||||
color3[i].g = color->g / 255.0f;
|
||||
color3[i].b = color->b / 255.0f;
|
||||
color3[i].a = color->a / 255.0f;
|
||||
color2 += color_stride;
|
||||
color = (const SDL_Color*)color2;
|
||||
}
|
||||
return SDL_RenderGeometryRaw(renderer, texture, xy, xy_stride, color3, sizeof(*color3), uv, uv_stride, num_vertices, indices, num_indices, size_indices);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer)
|
||||
{
|
||||
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
|
||||
|
||||
// If there's a scale factor set by the user, use that instead
|
||||
// If the user has specified a scale factor to SDL_Renderer already via SDL_RenderSetScale(), SDL will scale whatever we pass
|
||||
// to SDL_RenderGeometryRaw() by that scale factor. In that case we don't want to be also scaling it ourselves here.
|
||||
float rsx = 1.0f;
|
||||
float rsy = 1.0f;
|
||||
SDL_GetRenderScale(renderer, &rsx, &rsy);
|
||||
ImVec2 render_scale;
|
||||
render_scale.x = (rsx == 1.0f) ? draw_data->FramebufferScale.x : 1.0f;
|
||||
render_scale.y = (rsy == 1.0f) ? draw_data->FramebufferScale.y : 1.0f;
|
||||
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * render_scale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * render_scale.y);
|
||||
if (fb_width == 0 || fb_height == 0)
|
||||
return;
|
||||
|
||||
// Backup SDL_Renderer state that will be modified to restore it afterwards
|
||||
struct BackupSDLRendererState
|
||||
{
|
||||
SDL_Rect Viewport;
|
||||
bool ViewportEnabled;
|
||||
bool ClipEnabled;
|
||||
SDL_Rect ClipRect;
|
||||
};
|
||||
BackupSDLRendererState old = {};
|
||||
old.ViewportEnabled = SDL_RenderViewportSet(renderer);
|
||||
old.ClipEnabled = SDL_RenderClipEnabled(renderer);
|
||||
SDL_GetRenderViewport(renderer, &old.Viewport);
|
||||
SDL_GetRenderClipRect(renderer, &old.ClipRect);
|
||||
|
||||
// Setup desired state
|
||||
ImGui_ImplSDLRenderer3_SetupRenderState(renderer);
|
||||
|
||||
// Setup render state structure (for callbacks and custom texture bindings)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
ImGui_ImplSDLRenderer3_RenderState render_state;
|
||||
render_state.Renderer = renderer;
|
||||
platform_io.Renderer_RenderState = &render_state;
|
||||
|
||||
// Will project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||
ImVec2 clip_scale = render_scale;
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
|
||||
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplSDLRenderer3_SetupRenderState(renderer);
|
||||
else
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||
if (clip_min.x < 0.0f) { clip_min.x = 0.0f; }
|
||||
if (clip_min.y < 0.0f) { clip_min.y = 0.0f; }
|
||||
if (clip_max.x > (float)fb_width) { clip_max.x = (float)fb_width; }
|
||||
if (clip_max.y > (float)fb_height) { clip_max.y = (float)fb_height; }
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
SDL_Rect r = { (int)(clip_min.x), (int)(clip_min.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y) };
|
||||
SDL_SetRenderClipRect(renderer, &r);
|
||||
|
||||
const float* xy = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, pos));
|
||||
const float* uv = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, uv));
|
||||
const SDL_Color* color = (const SDL_Color*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col)); // SDL 2.0.19+
|
||||
|
||||
// Bind texture, Draw
|
||||
SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
|
||||
SDL_RenderGeometryRaw8BitColor(renderer, bd->ColorBuffer, tex,
|
||||
xy, (int)sizeof(ImDrawVert),
|
||||
color, (int)sizeof(ImDrawVert),
|
||||
uv, (int)sizeof(ImDrawVert),
|
||||
draw_list->VtxBuffer.Size - pcmd->VtxOffset,
|
||||
idx_buffer + pcmd->IdxOffset, pcmd->ElemCount, sizeof(ImDrawIdx));
|
||||
}
|
||||
}
|
||||
}
|
||||
platform_io.Renderer_RenderState = nullptr;
|
||||
|
||||
// Restore modified SDL_Renderer state
|
||||
SDL_SetRenderViewport(renderer, old.ViewportEnabled ? &old.Viewport : nullptr);
|
||||
SDL_SetRenderClipRect(renderer, old.ClipEnabled ? &old.ClipRect : nullptr);
|
||||
}
|
||||
|
||||
// Called by Init/NewFrame/Shutdown
|
||||
bool ImGui_ImplSDLRenderer3_CreateFontsTexture()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
|
||||
|
||||
// Build texture atlas
|
||||
unsigned char* pixels;
|
||||
int width, height;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bit (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
|
||||
|
||||
// Upload texture to graphics system
|
||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||
bd->FontTexture = SDL_CreateTexture(bd->Renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, width, height);
|
||||
if (bd->FontTexture == nullptr)
|
||||
{
|
||||
SDL_Log("error creating texture");
|
||||
return false;
|
||||
}
|
||||
SDL_UpdateTexture(bd->FontTexture, nullptr, pixels, 4 * width);
|
||||
SDL_SetTextureBlendMode(bd->FontTexture, SDL_BLENDMODE_BLEND);
|
||||
SDL_SetTextureScaleMode(bd->FontTexture, SDL_SCALEMODE_LINEAR);
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID((ImTextureID)(intptr_t)bd->FontTexture);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLRenderer3_DestroyFontsTexture()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
|
||||
if (bd->FontTexture)
|
||||
{
|
||||
io.Fonts->SetTexID(0);
|
||||
SDL_DestroyTexture(bd->FontTexture);
|
||||
bd->FontTexture = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGui_ImplSDLRenderer3_CreateDeviceObjects()
|
||||
{
|
||||
return ImGui_ImplSDLRenderer3_CreateFontsTexture();
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLRenderer3_DestroyDeviceObjects()
|
||||
{
|
||||
ImGui_ImplSDLRenderer3_DestroyFontsTexture();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
@@ -0,0 +1,53 @@
|
||||
// dear imgui: Renderer Backend for SDL_Renderer for SDL3
|
||||
// (Requires: SDL 3.1.8+)
|
||||
|
||||
// Note that SDL_Renderer is an _optional_ component of SDL3, which IMHO is now largely obsolete.
|
||||
// For a multi-platform app consider using other technologies:
|
||||
// - SDL3+SDL_GPU: SDL_GPU is SDL3 new graphics abstraction API.
|
||||
// - SDL3+DirectX, SDL3+OpenGL, SDL3+Vulkan: combine SDL with dedicated renderers.
|
||||
// If your application wants to render any non trivial amount of graphics other than UI,
|
||||
// please be aware that SDL_Renderer currently offers a limited graphic API to the end-user
|
||||
// and it might be difficult to step out of those boundaries.
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
||||
|
||||
// You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
struct SDL_Renderer;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer3_Init(SDL_Renderer* renderer);
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer);
|
||||
|
||||
// Called by Init/NewFrame/Shutdown
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer3_CreateFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_DestroyFontsTexture();
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer3_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_DestroyDeviceObjects();
|
||||
|
||||
// [BETA] Selected render state data shared with callbacks.
|
||||
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplSDLRenderer3_RenderDrawData() call.
|
||||
// (Please open an issue if you feel you need access to more data)
|
||||
struct ImGui_ImplSDLRenderer3_RenderState
|
||||
{
|
||||
SDL_Renderer* Renderer;
|
||||
};
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
+581
-273
File diff suppressed because it is too large
Load Diff
+99
-36
@@ -2,21 +2,22 @@
|
||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||
|
||||
// Implemented features:
|
||||
// [x] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [!] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Call ImGui_ImplVulkan_AddTexture() to register one. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// [x] Renderer: Multi-viewport / platform windows. With issues (flickering when creating a new viewport).
|
||||
|
||||
// Important: on 32-bit systems, user texture binding is only supported if your imconfig file has '#define ImTextureID ImU64'.
|
||||
// See imgui_impl_vulkan.cpp file for details.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
// The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification.
|
||||
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app.
|
||||
// - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h.
|
||||
// You will use those if you want to use this rendering backend in your engine/app.
|
||||
@@ -25,6 +26,7 @@
|
||||
// Read comments in imgui_impl_vulkan.h.
|
||||
|
||||
#pragma once
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
|
||||
// [Configuration] in order to use a custom Vulkan function loader:
|
||||
@@ -39,14 +41,39 @@
|
||||
// If you have no idea what this is, leave it alone!
|
||||
//#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES
|
||||
|
||||
// Vulkan includes
|
||||
// Convenience support for Volk
|
||||
// (you can also technically use IMGUI_IMPL_VULKAN_NO_PROTOTYPES + wrap Volk via ImGui_ImplVulkan_LoadFunctions().)
|
||||
//#define IMGUI_IMPL_VULKAN_USE_VOLK
|
||||
|
||||
#if defined(IMGUI_IMPL_VULKAN_NO_PROTOTYPES) && !defined(VK_NO_PROTOTYPES)
|
||||
#define VK_NO_PROTOTYPES
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR) && !defined(NOMINMAX)
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
// Vulkan includes
|
||||
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
|
||||
#include <volk.h>
|
||||
#else
|
||||
#include <vulkan/vulkan.h>
|
||||
#endif
|
||||
#if defined(VK_VERSION_1_3) || defined(VK_KHR_dynamic_rendering)
|
||||
#define IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
#endif
|
||||
|
||||
// Current version of the backend use 1 descriptor for the font atlas + as many as additional calls done to ImGui_ImplVulkan_AddTexture().
|
||||
// It is expected that as early as Q1 2025 the backend will use a few more descriptors. Use this value + number of desired calls to ImGui_ImplVulkan_AddTexture().
|
||||
#define IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE (1) // Minimum per atlas
|
||||
|
||||
// Initialization data, for ImGui_ImplVulkan_Init()
|
||||
// [Please zero-clear before use!]
|
||||
// - About descriptor pool:
|
||||
// - A VkDescriptorPool should be created with VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
|
||||
// and must contain a pool size large enough to hold a small number of VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptors.
|
||||
// - As an convenience, by setting DescriptorPoolSize > 0 the backend will create one for you.
|
||||
// - About dynamic rendering:
|
||||
// - When using dynamic rendering, set UseDynamicRendering=true and fill PipelineRenderingCreateInfo structure.
|
||||
struct ImGui_ImplVulkan_InitInfo
|
||||
{
|
||||
VkInstance Instance;
|
||||
@@ -54,59 +81,93 @@ struct ImGui_ImplVulkan_InitInfo
|
||||
VkDevice Device;
|
||||
uint32_t QueueFamily;
|
||||
VkQueue Queue;
|
||||
VkDescriptorPool DescriptorPool; // See requirements in note above; ignored if using DescriptorPoolSize > 0
|
||||
VkRenderPass RenderPass; // Ignored if using dynamic rendering
|
||||
uint32_t MinImageCount; // >= 2
|
||||
uint32_t ImageCount; // >= MinImageCount
|
||||
VkSampleCountFlagBits MSAASamples; // 0 defaults to VK_SAMPLE_COUNT_1_BIT
|
||||
|
||||
// (Optional)
|
||||
VkPipelineCache PipelineCache;
|
||||
VkDescriptorPool DescriptorPool;
|
||||
uint32_t Subpass;
|
||||
uint32_t MinImageCount; // >= 2
|
||||
uint32_t ImageCount; // >= MinImageCount
|
||||
VkSampleCountFlagBits MSAASamples; // >= VK_SAMPLE_COUNT_1_BIT (0 -> default to VK_SAMPLE_COUNT_1_BIT)
|
||||
|
||||
// (Optional) Set to create internal descriptor pool instead of using DescriptorPool
|
||||
uint32_t DescriptorPoolSize;
|
||||
|
||||
// (Optional) Dynamic Rendering
|
||||
// Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3.
|
||||
bool UseDynamicRendering;
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo;
|
||||
#endif
|
||||
|
||||
// (Optional) Allocation, Debugging
|
||||
const VkAllocationCallbacks* Allocator;
|
||||
void (*CheckVkResultFn)(VkResult err);
|
||||
VkDeviceSize MinAllocationSize; // Minimum allocation size. Set to 1024*1024 to satisfy zealous best practices validation layer and waste a little memory.
|
||||
};
|
||||
|
||||
// Called by user code
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info, VkRenderPass render_pass);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline = VK_NULL_HANDLE);
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture(VkCommandBuffer command_buffer);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontUploadObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated)
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline = VK_NULL_HANDLE);
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated)
|
||||
|
||||
// Register a texture (VkDescriptorSet == ImTextureID)
|
||||
// FIXME: This is experimental in the sense that we are unsure how to best design/tackle this problem
|
||||
// Please post to https://github.com/ocornut/imgui/pull/914 if you have suggestions.
|
||||
IMGUI_IMPL_API VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image_view, VkImageLayout image_layout);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet descriptor_set);
|
||||
IMGUI_IMPL_API VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image_view, VkImageLayout image_layout);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet descriptor_set);
|
||||
|
||||
// Optional: load Vulkan functions with a custom function loader
|
||||
// This is only useful with IMGUI_IMPL_VULKAN_NO_PROTOTYPES / VK_NO_PROTOTYPES
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = nullptr);
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = nullptr);
|
||||
|
||||
// [BETA] Selected render state data shared with callbacks.
|
||||
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplVulkan_RenderDrawData() call.
|
||||
// (Please open an issue if you feel you need access to more data)
|
||||
struct ImGui_ImplVulkan_RenderState
|
||||
{
|
||||
VkCommandBuffer CommandBuffer;
|
||||
VkPipeline Pipeline;
|
||||
VkPipelineLayout PipelineLayout;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Internal / Miscellaneous Vulkan Helpers
|
||||
// (Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own engine/app.)
|
||||
//-------------------------------------------------------------------------
|
||||
// Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own engine/app.
|
||||
//
|
||||
// You probably do NOT need to use or care about those functions.
|
||||
// Those functions only exist because:
|
||||
// 1) they facilitate the readability and maintenance of the multiple main.cpp examples files.
|
||||
// 2) the multi-viewport / platform window implementation needs them internally.
|
||||
// Generally we avoid exposing any kind of superfluous high-level helpers in the bindings,
|
||||
// Generally we avoid exposing any kind of superfluous high-level helpers in the backends,
|
||||
// but it is too much code to duplicate everywhere so we exceptionally expose them.
|
||||
//
|
||||
// Your engine/app will likely _already_ have code to setup all that stuff (swap chain, render pass, frame buffers, etc.).
|
||||
// You may read this code to learn about Vulkan, but it is recommended you use you own custom tailored code to do equivalent work.
|
||||
// (The ImGui_ImplVulkanH_XXX functions do not interact with any of the state used by the regular ImGui_ImplVulkan_XXX functions)
|
||||
// Your engine/app will likely _already_ have code to setup all that stuff (swap chain,
|
||||
// render pass, frame buffers, etc.). You may read this code if you are curious, but
|
||||
// it is recommended you use you own custom tailored code to do equivalent work.
|
||||
//
|
||||
// We don't provide a strong guarantee that we won't change those functions API.
|
||||
//
|
||||
// The ImGui_ImplVulkanH_XXX functions should NOT interact with any of the state used
|
||||
// by the regular ImGui_ImplVulkan_XXX functions).
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
struct ImGui_ImplVulkanH_Frame;
|
||||
struct ImGui_ImplVulkanH_Window;
|
||||
|
||||
// Helpers
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateOrResizeWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wnd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Window* wnd, const VkAllocationCallbacks* allocator);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateOrResizeWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator);
|
||||
IMGUI_IMPL_API VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space);
|
||||
IMGUI_IMPL_API VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count);
|
||||
IMGUI_IMPL_API VkPhysicalDevice ImGui_ImplVulkanH_SelectPhysicalDevice(VkInstance instance);
|
||||
IMGUI_IMPL_API uint32_t ImGui_ImplVulkanH_SelectQueueFamilyIndex(VkPhysicalDevice physical_device);
|
||||
IMGUI_IMPL_API int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_mode);
|
||||
|
||||
// Helper structure to hold the data needed by one rendering frame
|
||||
@@ -139,14 +200,15 @@ struct ImGui_ImplVulkanH_Window
|
||||
VkSurfaceFormatKHR SurfaceFormat;
|
||||
VkPresentModeKHR PresentMode;
|
||||
VkRenderPass RenderPass;
|
||||
VkPipeline Pipeline; // The window pipeline may uses a different VkRenderPass than the one passed in ImGui_ImplVulkan_InitInfo
|
||||
bool UseDynamicRendering;
|
||||
bool ClearEnable;
|
||||
VkClearValue ClearValue;
|
||||
uint32_t FrameIndex; // Current frame being rendered to (0 <= FrameIndex < FrameInFlightCount)
|
||||
uint32_t ImageCount; // Number of simultaneous in-flight frames (returned by vkGetSwapchainImagesKHR, usually derived from min_image_count)
|
||||
uint32_t SemaphoreCount; // Number of simultaneous in-flight frames + 1, to be able to use it in vkAcquireNextImageKHR
|
||||
uint32_t SemaphoreIndex; // Current set of swapchain wait semaphores we're using (needs to be distinct from per frame data)
|
||||
ImGui_ImplVulkanH_Frame* Frames;
|
||||
ImGui_ImplVulkanH_FrameSemaphores* FrameSemaphores;
|
||||
ImVector<ImGui_ImplVulkanH_Frame> Frames;
|
||||
ImVector<ImGui_ImplVulkanH_FrameSemaphores> FrameSemaphores;
|
||||
|
||||
ImGui_ImplVulkanH_Window()
|
||||
{
|
||||
@@ -156,3 +218,4 @@ struct ImGui_ImplVulkanH_Window
|
||||
}
|
||||
};
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+860
@@ -0,0 +1,860 @@
|
||||
// dear imgui: Renderer for WebGPU
|
||||
// This needs to be used along with a Platform Binding (e.g. GLFW)
|
||||
// (Please note that WebGPU is currently experimental, will not run on non-beta browsers, and may break.)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows). Not meaningful on the web.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2024-10-14: Update Dawn support for change of string usages. (#8082, #8083)
|
||||
// 2024-10-07: Expose selected render state in ImGui_ImplWGPU_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||
// 2024-10-07: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||
// 2024-09-16: Added support for optional IMGUI_IMPL_WEBGPU_BACKEND_DAWN / IMGUI_IMPL_WEBGPU_BACKEND_WGPU define to handle ever-changing native implementations. (#7977)
|
||||
// 2024-01-22: Added configurable PipelineMultisampleState struct. (#7240)
|
||||
// 2024-01-22: (Breaking) ImGui_ImplWGPU_Init() now takes a ImGui_ImplWGPU_InitInfo structure instead of variety of parameters, allowing for easier further changes.
|
||||
// 2024-01-22: Fixed pipeline layout leak. (#7245)
|
||||
// 2024-01-17: Explicitly fill all of WGPUDepthStencilState since standard removed defaults.
|
||||
// 2023-07-13: Use WGPUShaderModuleWGSLDescriptor's code instead of source. use WGPUMipmapFilterMode_Linear instead of WGPUFilterMode_Linear. (#6602)
|
||||
// 2023-04-11: Align buffer sizes. Use WGSL shaders instead of precompiled SPIR-V.
|
||||
// 2023-04-11: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2023-01-25: Revert automatic pipeline layout generation (see https://github.com/gpuweb/gpuweb/issues/2470)
|
||||
// 2022-11-24: Fixed validation error with default depth buffer settings.
|
||||
// 2022-11-10: Fixed rendering when a depth buffer is enabled. Added 'WGPUTextureFormat depth_format' parameter to ImGui_ImplWGPU_Init().
|
||||
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||
// 2021-11-29: Passing explicit buffer sizes to wgpuRenderPassEncoderSetVertexBuffer()/wgpuRenderPassEncoderSetIndexBuffer().
|
||||
// 2021-08-24: Fixed for latest specs.
|
||||
// 2021-05-24: Add support for draw_data->FramebufferScale.
|
||||
// 2021-05-19: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
// 2021-05-16: Update to latest WebGPU specs (compatible with Emscripten 2.0.20 and Chrome Canary 92).
|
||||
// 2021-02-18: Change blending equation to preserve alpha in output buffer.
|
||||
// 2021-01-28: Initial version.
|
||||
|
||||
// When targeting native platforms (i.e. NOT emscripten), one of IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
// or IMGUI_IMPL_WEBGPU_BACKEND_WGPU must be provided. See imgui_impl_wgpu.h for more details.
|
||||
#ifndef __EMSCRIPTEN__
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) == defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
#error exactly one of IMGUI_IMPL_WEBGPU_BACKEND_DAWN or IMGUI_IMPL_WEBGPU_BACKEND_WGPU must be defined!
|
||||
#endif
|
||||
#else
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
#error neither IMGUI_IMPL_WEBGPU_BACKEND_DAWN nor IMGUI_IMPL_WEBGPU_BACKEND_WGPU may be defined if targeting emscripten!
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_wgpu.h"
|
||||
#include <limits.h>
|
||||
#include <webgpu/webgpu.h>
|
||||
|
||||
// Dear ImGui prototypes from imgui_internal.h
|
||||
extern ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed = 0);
|
||||
#define MEMALIGN(_SIZE,_ALIGN) (((_SIZE) + ((_ALIGN) - 1)) & ~((_ALIGN) - 1)) // Memory align (copied from IM_ALIGN() macro).
|
||||
|
||||
// WebGPU data
|
||||
struct RenderResources
|
||||
{
|
||||
WGPUTexture FontTexture = nullptr; // Font texture
|
||||
WGPUTextureView FontTextureView = nullptr; // Texture view for font texture
|
||||
WGPUSampler Sampler = nullptr; // Sampler for the font texture
|
||||
WGPUBuffer Uniforms = nullptr; // Shader uniforms
|
||||
WGPUBindGroup CommonBindGroup = nullptr; // Resources bind-group to bind the common resources to pipeline
|
||||
ImGuiStorage ImageBindGroups; // Resources bind-group to bind the font/image resources to pipeline (this is a key->value map)
|
||||
WGPUBindGroup ImageBindGroup = nullptr; // Default font-resource of Dear ImGui
|
||||
WGPUBindGroupLayout ImageBindGroupLayout = nullptr; // Cache layout used for the image bind group. Avoids allocating unnecessary JS objects when working with WebASM
|
||||
};
|
||||
|
||||
struct FrameResources
|
||||
{
|
||||
WGPUBuffer IndexBuffer;
|
||||
WGPUBuffer VertexBuffer;
|
||||
ImDrawIdx* IndexBufferHost;
|
||||
ImDrawVert* VertexBufferHost;
|
||||
int IndexBufferSize;
|
||||
int VertexBufferSize;
|
||||
};
|
||||
|
||||
struct Uniforms
|
||||
{
|
||||
float MVP[4][4];
|
||||
float Gamma;
|
||||
};
|
||||
|
||||
struct ImGui_ImplWGPU_Data
|
||||
{
|
||||
ImGui_ImplWGPU_InitInfo initInfo;
|
||||
WGPUDevice wgpuDevice = nullptr;
|
||||
WGPUQueue defaultQueue = nullptr;
|
||||
WGPUTextureFormat renderTargetFormat = WGPUTextureFormat_Undefined;
|
||||
WGPUTextureFormat depthStencilFormat = WGPUTextureFormat_Undefined;
|
||||
WGPURenderPipeline pipelineState = nullptr;
|
||||
|
||||
RenderResources renderResources;
|
||||
FrameResources* pFrameResources = nullptr;
|
||||
unsigned int numFramesInFlight = 0;
|
||||
unsigned int frameIndex = UINT_MAX;
|
||||
};
|
||||
|
||||
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||
static ImGui_ImplWGPU_Data* ImGui_ImplWGPU_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplWGPU_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SHADERS
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static const char __shader_vert_wgsl[] = R"(
|
||||
struct VertexInput {
|
||||
@location(0) position: vec2<f32>,
|
||||
@location(1) uv: vec2<f32>,
|
||||
@location(2) color: vec4<f32>,
|
||||
};
|
||||
|
||||
struct VertexOutput {
|
||||
@builtin(position) position: vec4<f32>,
|
||||
@location(0) color: vec4<f32>,
|
||||
@location(1) uv: vec2<f32>,
|
||||
};
|
||||
|
||||
struct Uniforms {
|
||||
mvp: mat4x4<f32>,
|
||||
gamma: f32,
|
||||
};
|
||||
|
||||
@group(0) @binding(0) var<uniform> uniforms: Uniforms;
|
||||
|
||||
@vertex
|
||||
fn main(in: VertexInput) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.position = uniforms.mvp * vec4<f32>(in.position, 0.0, 1.0);
|
||||
out.color = in.color;
|
||||
out.uv = in.uv;
|
||||
return out;
|
||||
}
|
||||
)";
|
||||
|
||||
static const char __shader_frag_wgsl[] = R"(
|
||||
struct VertexOutput {
|
||||
@builtin(position) position: vec4<f32>,
|
||||
@location(0) color: vec4<f32>,
|
||||
@location(1) uv: vec2<f32>,
|
||||
};
|
||||
|
||||
struct Uniforms {
|
||||
mvp: mat4x4<f32>,
|
||||
gamma: f32,
|
||||
};
|
||||
|
||||
@group(0) @binding(0) var<uniform> uniforms: Uniforms;
|
||||
@group(0) @binding(1) var s: sampler;
|
||||
@group(1) @binding(0) var t: texture_2d<f32>;
|
||||
|
||||
@fragment
|
||||
fn main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||
let color = in.color * textureSample(t, s, in.uv);
|
||||
let corrected_color = pow(color.rgb, vec3<f32>(uniforms.gamma));
|
||||
return vec4<f32>(corrected_color, color.a);
|
||||
}
|
||||
)";
|
||||
|
||||
static void SafeRelease(ImDrawIdx*& res)
|
||||
{
|
||||
if (res)
|
||||
delete[] res;
|
||||
res = nullptr;
|
||||
}
|
||||
static void SafeRelease(ImDrawVert*& res)
|
||||
{
|
||||
if (res)
|
||||
delete[] res;
|
||||
res = nullptr;
|
||||
}
|
||||
static void SafeRelease(WGPUBindGroupLayout& res)
|
||||
{
|
||||
if (res)
|
||||
wgpuBindGroupLayoutRelease(res);
|
||||
res = nullptr;
|
||||
}
|
||||
static void SafeRelease(WGPUBindGroup& res)
|
||||
{
|
||||
if (res)
|
||||
wgpuBindGroupRelease(res);
|
||||
res = nullptr;
|
||||
}
|
||||
static void SafeRelease(WGPUBuffer& res)
|
||||
{
|
||||
if (res)
|
||||
wgpuBufferRelease(res);
|
||||
res = nullptr;
|
||||
}
|
||||
static void SafeRelease(WGPUPipelineLayout& res)
|
||||
{
|
||||
if (res)
|
||||
wgpuPipelineLayoutRelease(res);
|
||||
res = nullptr;
|
||||
}
|
||||
static void SafeRelease(WGPURenderPipeline& res)
|
||||
{
|
||||
if (res)
|
||||
wgpuRenderPipelineRelease(res);
|
||||
res = nullptr;
|
||||
}
|
||||
static void SafeRelease(WGPUSampler& res)
|
||||
{
|
||||
if (res)
|
||||
wgpuSamplerRelease(res);
|
||||
res = nullptr;
|
||||
}
|
||||
static void SafeRelease(WGPUShaderModule& res)
|
||||
{
|
||||
if (res)
|
||||
wgpuShaderModuleRelease(res);
|
||||
res = nullptr;
|
||||
}
|
||||
static void SafeRelease(WGPUTextureView& res)
|
||||
{
|
||||
if (res)
|
||||
wgpuTextureViewRelease(res);
|
||||
res = nullptr;
|
||||
}
|
||||
static void SafeRelease(WGPUTexture& res)
|
||||
{
|
||||
if (res)
|
||||
wgpuTextureRelease(res);
|
||||
res = nullptr;
|
||||
}
|
||||
|
||||
static void SafeRelease(RenderResources& res)
|
||||
{
|
||||
SafeRelease(res.FontTexture);
|
||||
SafeRelease(res.FontTextureView);
|
||||
SafeRelease(res.Sampler);
|
||||
SafeRelease(res.Uniforms);
|
||||
SafeRelease(res.CommonBindGroup);
|
||||
SafeRelease(res.ImageBindGroup);
|
||||
SafeRelease(res.ImageBindGroupLayout);
|
||||
};
|
||||
|
||||
static void SafeRelease(FrameResources& res)
|
||||
{
|
||||
SafeRelease(res.IndexBuffer);
|
||||
SafeRelease(res.VertexBuffer);
|
||||
SafeRelease(res.IndexBufferHost);
|
||||
SafeRelease(res.VertexBufferHost);
|
||||
}
|
||||
|
||||
static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(const char* wgsl_source)
|
||||
{
|
||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
WGPUShaderSourceWGSL wgsl_desc = {};
|
||||
wgsl_desc.chain.sType = WGPUSType_ShaderSourceWGSL;
|
||||
wgsl_desc.code = { wgsl_source, WGPU_STRLEN };
|
||||
#else
|
||||
WGPUShaderModuleWGSLDescriptor wgsl_desc = {};
|
||||
wgsl_desc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor;
|
||||
wgsl_desc.code = wgsl_source;
|
||||
#endif
|
||||
|
||||
WGPUShaderModuleDescriptor desc = {};
|
||||
desc.nextInChain = reinterpret_cast<WGPUChainedStruct*>(&wgsl_desc);
|
||||
|
||||
WGPUProgrammableStageDescriptor stage_desc = {};
|
||||
stage_desc.module = wgpuDeviceCreateShaderModule(bd->wgpuDevice, &desc);
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
stage_desc.entryPoint = { "main", WGPU_STRLEN };
|
||||
#else
|
||||
stage_desc.entryPoint = "main";
|
||||
#endif
|
||||
return stage_desc;
|
||||
}
|
||||
|
||||
static WGPUBindGroup ImGui_ImplWGPU_CreateImageBindGroup(WGPUBindGroupLayout layout, WGPUTextureView texture)
|
||||
{
|
||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||
WGPUBindGroupEntry image_bg_entries[] = { { nullptr, 0, 0, 0, 0, 0, texture } };
|
||||
|
||||
WGPUBindGroupDescriptor image_bg_descriptor = {};
|
||||
image_bg_descriptor.layout = layout;
|
||||
image_bg_descriptor.entryCount = sizeof(image_bg_entries) / sizeof(WGPUBindGroupEntry);
|
||||
image_bg_descriptor.entries = image_bg_entries;
|
||||
return wgpuDeviceCreateBindGroup(bd->wgpuDevice, &image_bg_descriptor);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWGPU_SetupRenderState(ImDrawData* draw_data, WGPURenderPassEncoder ctx, FrameResources* fr)
|
||||
{
|
||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||
|
||||
// Setup orthographic projection matrix into our constant buffer
|
||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right).
|
||||
{
|
||||
float L = draw_data->DisplayPos.x;
|
||||
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||
float T = draw_data->DisplayPos.y;
|
||||
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
|
||||
float mvp[4][4] =
|
||||
{
|
||||
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.5f, 0.0f },
|
||||
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
|
||||
};
|
||||
wgpuQueueWriteBuffer(bd->defaultQueue, bd->renderResources.Uniforms, offsetof(Uniforms, MVP), mvp, sizeof(Uniforms::MVP));
|
||||
float gamma;
|
||||
switch (bd->renderTargetFormat)
|
||||
{
|
||||
case WGPUTextureFormat_ASTC10x10UnormSrgb:
|
||||
case WGPUTextureFormat_ASTC10x5UnormSrgb:
|
||||
case WGPUTextureFormat_ASTC10x6UnormSrgb:
|
||||
case WGPUTextureFormat_ASTC10x8UnormSrgb:
|
||||
case WGPUTextureFormat_ASTC12x10UnormSrgb:
|
||||
case WGPUTextureFormat_ASTC12x12UnormSrgb:
|
||||
case WGPUTextureFormat_ASTC4x4UnormSrgb:
|
||||
case WGPUTextureFormat_ASTC5x5UnormSrgb:
|
||||
case WGPUTextureFormat_ASTC6x5UnormSrgb:
|
||||
case WGPUTextureFormat_ASTC6x6UnormSrgb:
|
||||
case WGPUTextureFormat_ASTC8x5UnormSrgb:
|
||||
case WGPUTextureFormat_ASTC8x6UnormSrgb:
|
||||
case WGPUTextureFormat_ASTC8x8UnormSrgb:
|
||||
case WGPUTextureFormat_BC1RGBAUnormSrgb:
|
||||
case WGPUTextureFormat_BC2RGBAUnormSrgb:
|
||||
case WGPUTextureFormat_BC3RGBAUnormSrgb:
|
||||
case WGPUTextureFormat_BC7RGBAUnormSrgb:
|
||||
case WGPUTextureFormat_BGRA8UnormSrgb:
|
||||
case WGPUTextureFormat_ETC2RGB8A1UnormSrgb:
|
||||
case WGPUTextureFormat_ETC2RGB8UnormSrgb:
|
||||
case WGPUTextureFormat_ETC2RGBA8UnormSrgb:
|
||||
case WGPUTextureFormat_RGBA8UnormSrgb:
|
||||
gamma = 2.2f;
|
||||
break;
|
||||
default:
|
||||
gamma = 1.0f;
|
||||
}
|
||||
wgpuQueueWriteBuffer(bd->defaultQueue, bd->renderResources.Uniforms, offsetof(Uniforms, Gamma), &gamma, sizeof(Uniforms::Gamma));
|
||||
}
|
||||
|
||||
// Setup viewport
|
||||
wgpuRenderPassEncoderSetViewport(ctx, 0, 0, draw_data->FramebufferScale.x * draw_data->DisplaySize.x, draw_data->FramebufferScale.y * draw_data->DisplaySize.y, 0, 1);
|
||||
|
||||
// Bind shader and vertex buffers
|
||||
wgpuRenderPassEncoderSetVertexBuffer(ctx, 0, fr->VertexBuffer, 0, fr->VertexBufferSize * sizeof(ImDrawVert));
|
||||
wgpuRenderPassEncoderSetIndexBuffer(ctx, fr->IndexBuffer, sizeof(ImDrawIdx) == 2 ? WGPUIndexFormat_Uint16 : WGPUIndexFormat_Uint32, 0, fr->IndexBufferSize * sizeof(ImDrawIdx));
|
||||
wgpuRenderPassEncoderSetPipeline(ctx, bd->pipelineState);
|
||||
wgpuRenderPassEncoderSetBindGroup(ctx, 0, bd->renderResources.CommonBindGroup, 0, nullptr);
|
||||
|
||||
// Setup blend factor
|
||||
WGPUColor blend_color = { 0.f, 0.f, 0.f, 0.f };
|
||||
wgpuRenderPassEncoderSetBlendConstant(ctx, &blend_color);
|
||||
}
|
||||
|
||||
// Render function
|
||||
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
|
||||
void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder)
|
||||
{
|
||||
// Avoid rendering when minimized
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdListsCount == 0)
|
||||
return;
|
||||
|
||||
// FIXME: Assuming that this only gets called once per frame!
|
||||
// If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator.
|
||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||
bd->frameIndex = bd->frameIndex + 1;
|
||||
FrameResources* fr = &bd->pFrameResources[bd->frameIndex % bd->numFramesInFlight];
|
||||
|
||||
// Create and grow vertex/index buffers if needed
|
||||
if (fr->VertexBuffer == nullptr || fr->VertexBufferSize < draw_data->TotalVtxCount)
|
||||
{
|
||||
if (fr->VertexBuffer)
|
||||
{
|
||||
wgpuBufferDestroy(fr->VertexBuffer);
|
||||
wgpuBufferRelease(fr->VertexBuffer);
|
||||
}
|
||||
SafeRelease(fr->VertexBufferHost);
|
||||
fr->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||
|
||||
WGPUBufferDescriptor vb_desc =
|
||||
{
|
||||
nullptr,
|
||||
"Dear ImGui Vertex buffer",
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
WGPU_STRLEN,
|
||||
#endif
|
||||
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex,
|
||||
MEMALIGN(fr->VertexBufferSize * sizeof(ImDrawVert), 4),
|
||||
false
|
||||
};
|
||||
fr->VertexBuffer = wgpuDeviceCreateBuffer(bd->wgpuDevice, &vb_desc);
|
||||
if (!fr->VertexBuffer)
|
||||
return;
|
||||
|
||||
fr->VertexBufferHost = new ImDrawVert[fr->VertexBufferSize];
|
||||
}
|
||||
if (fr->IndexBuffer == nullptr || fr->IndexBufferSize < draw_data->TotalIdxCount)
|
||||
{
|
||||
if (fr->IndexBuffer)
|
||||
{
|
||||
wgpuBufferDestroy(fr->IndexBuffer);
|
||||
wgpuBufferRelease(fr->IndexBuffer);
|
||||
}
|
||||
SafeRelease(fr->IndexBufferHost);
|
||||
fr->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||
|
||||
WGPUBufferDescriptor ib_desc =
|
||||
{
|
||||
nullptr,
|
||||
"Dear ImGui Index buffer",
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
WGPU_STRLEN,
|
||||
#endif
|
||||
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index,
|
||||
MEMALIGN(fr->IndexBufferSize * sizeof(ImDrawIdx), 4),
|
||||
false
|
||||
};
|
||||
fr->IndexBuffer = wgpuDeviceCreateBuffer(bd->wgpuDevice, &ib_desc);
|
||||
if (!fr->IndexBuffer)
|
||||
return;
|
||||
|
||||
fr->IndexBufferHost = new ImDrawIdx[fr->IndexBufferSize];
|
||||
}
|
||||
|
||||
// Upload vertex/index data into a single contiguous GPU buffer
|
||||
ImDrawVert* vtx_dst = (ImDrawVert*)fr->VertexBufferHost;
|
||||
ImDrawIdx* idx_dst = (ImDrawIdx*)fr->IndexBufferHost;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
idx_dst += draw_list->IdxBuffer.Size;
|
||||
}
|
||||
int64_t vb_write_size = MEMALIGN((char*)vtx_dst - (char*)fr->VertexBufferHost, 4);
|
||||
int64_t ib_write_size = MEMALIGN((char*)idx_dst - (char*)fr->IndexBufferHost, 4);
|
||||
wgpuQueueWriteBuffer(bd->defaultQueue, fr->VertexBuffer, 0, fr->VertexBufferHost, vb_write_size);
|
||||
wgpuQueueWriteBuffer(bd->defaultQueue, fr->IndexBuffer, 0, fr->IndexBufferHost, ib_write_size);
|
||||
|
||||
// Setup desired render state
|
||||
ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr);
|
||||
|
||||
// Setup render state structure (for callbacks and custom texture bindings)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
ImGui_ImplWGPU_RenderState render_state;
|
||||
render_state.Device = bd->wgpuDevice;
|
||||
render_state.RenderPassEncoder = pass_encoder;
|
||||
platform_io.Renderer_RenderState = &render_state;
|
||||
|
||||
// Render command lists
|
||||
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||
int global_vtx_offset = 0;
|
||||
int global_idx_offset = 0;
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale;
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != nullptr)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr);
|
||||
else
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bind custom texture
|
||||
ImTextureID tex_id = pcmd->GetTexID();
|
||||
ImGuiID tex_id_hash = ImHashData(&tex_id, sizeof(tex_id));
|
||||
auto bind_group = bd->renderResources.ImageBindGroups.GetVoidPtr(tex_id_hash);
|
||||
if (bind_group)
|
||||
{
|
||||
wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, (WGPUBindGroup)bind_group, 0, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(bd->renderResources.ImageBindGroupLayout, (WGPUTextureView)tex_id);
|
||||
bd->renderResources.ImageBindGroups.SetVoidPtr(tex_id_hash, image_bind_group);
|
||||
wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, image_bind_group, 0, nullptr);
|
||||
}
|
||||
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||
|
||||
// Clamp to viewport as wgpuRenderPassEncoderSetScissorRect() won't accept values that are off bounds
|
||||
if (clip_min.x < 0.0f) { clip_min.x = 0.0f; }
|
||||
if (clip_min.y < 0.0f) { clip_min.y = 0.0f; }
|
||||
if (clip_max.x > fb_width) { clip_max.x = (float)fb_width; }
|
||||
if (clip_max.y > fb_height) { clip_max.y = (float)fb_height; }
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
// Apply scissor/clipping rectangle, Draw
|
||||
wgpuRenderPassEncoderSetScissorRect(pass_encoder, (uint32_t)clip_min.x, (uint32_t)clip_min.y, (uint32_t)(clip_max.x - clip_min.x), (uint32_t)(clip_max.y - clip_min.y));
|
||||
wgpuRenderPassEncoderDrawIndexed(pass_encoder, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||
}
|
||||
}
|
||||
global_idx_offset += draw_list->IdxBuffer.Size;
|
||||
global_vtx_offset += draw_list->VtxBuffer.Size;
|
||||
}
|
||||
platform_io.Renderer_RenderState = nullptr;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWGPU_CreateFontsTexture()
|
||||
{
|
||||
// Build texture atlas
|
||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
unsigned char* pixels;
|
||||
int width, height, size_pp;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height, &size_pp);
|
||||
|
||||
// Upload texture to graphics system
|
||||
{
|
||||
WGPUTextureDescriptor tex_desc = {};
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
tex_desc.label = { "Dear ImGui Font Texture", WGPU_STRLEN };
|
||||
#else
|
||||
tex_desc.label = "Dear ImGui Font Texture";
|
||||
#endif
|
||||
tex_desc.dimension = WGPUTextureDimension_2D;
|
||||
tex_desc.size.width = width;
|
||||
tex_desc.size.height = height;
|
||||
tex_desc.size.depthOrArrayLayers = 1;
|
||||
tex_desc.sampleCount = 1;
|
||||
tex_desc.format = WGPUTextureFormat_RGBA8Unorm;
|
||||
tex_desc.mipLevelCount = 1;
|
||||
tex_desc.usage = WGPUTextureUsage_CopyDst | WGPUTextureUsage_TextureBinding;
|
||||
bd->renderResources.FontTexture = wgpuDeviceCreateTexture(bd->wgpuDevice, &tex_desc);
|
||||
|
||||
WGPUTextureViewDescriptor tex_view_desc = {};
|
||||
tex_view_desc.format = WGPUTextureFormat_RGBA8Unorm;
|
||||
tex_view_desc.dimension = WGPUTextureViewDimension_2D;
|
||||
tex_view_desc.baseMipLevel = 0;
|
||||
tex_view_desc.mipLevelCount = 1;
|
||||
tex_view_desc.baseArrayLayer = 0;
|
||||
tex_view_desc.arrayLayerCount = 1;
|
||||
tex_view_desc.aspect = WGPUTextureAspect_All;
|
||||
bd->renderResources.FontTextureView = wgpuTextureCreateView(bd->renderResources.FontTexture, &tex_view_desc);
|
||||
}
|
||||
|
||||
// Upload texture data
|
||||
{
|
||||
WGPUImageCopyTexture dst_view = {};
|
||||
dst_view.texture = bd->renderResources.FontTexture;
|
||||
dst_view.mipLevel = 0;
|
||||
dst_view.origin = { 0, 0, 0 };
|
||||
dst_view.aspect = WGPUTextureAspect_All;
|
||||
WGPUTextureDataLayout layout = {};
|
||||
layout.offset = 0;
|
||||
layout.bytesPerRow = width * size_pp;
|
||||
layout.rowsPerImage = height;
|
||||
WGPUExtent3D size = { (uint32_t)width, (uint32_t)height, 1 };
|
||||
wgpuQueueWriteTexture(bd->defaultQueue, &dst_view, pixels, (uint32_t)(width * size_pp * height), &layout, &size);
|
||||
}
|
||||
|
||||
// Create the associated sampler
|
||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||
{
|
||||
WGPUSamplerDescriptor sampler_desc = {};
|
||||
sampler_desc.minFilter = WGPUFilterMode_Linear;
|
||||
sampler_desc.magFilter = WGPUFilterMode_Linear;
|
||||
sampler_desc.mipmapFilter = WGPUMipmapFilterMode_Linear;
|
||||
sampler_desc.addressModeU = WGPUAddressMode_ClampToEdge;
|
||||
sampler_desc.addressModeV = WGPUAddressMode_ClampToEdge;
|
||||
sampler_desc.addressModeW = WGPUAddressMode_ClampToEdge;
|
||||
sampler_desc.maxAnisotropy = 1;
|
||||
bd->renderResources.Sampler = wgpuDeviceCreateSampler(bd->wgpuDevice, &sampler_desc);
|
||||
}
|
||||
|
||||
// Store our identifier
|
||||
static_assert(sizeof(ImTextureID) >= sizeof(bd->renderResources.FontTexture), "Can't pack descriptor handle into TexID, 32-bit not supported yet.");
|
||||
io.Fonts->SetTexID((ImTextureID)bd->renderResources.FontTextureView);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWGPU_CreateUniformBuffer()
|
||||
{
|
||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||
WGPUBufferDescriptor ub_desc =
|
||||
{
|
||||
nullptr,
|
||||
"Dear ImGui Uniform buffer",
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
WGPU_STRLEN,
|
||||
#endif
|
||||
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Uniform,
|
||||
MEMALIGN(sizeof(Uniforms), 16),
|
||||
false
|
||||
};
|
||||
bd->renderResources.Uniforms = wgpuDeviceCreateBuffer(bd->wgpuDevice, &ub_desc);
|
||||
}
|
||||
|
||||
bool ImGui_ImplWGPU_CreateDeviceObjects()
|
||||
{
|
||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||
if (!bd->wgpuDevice)
|
||||
return false;
|
||||
if (bd->pipelineState)
|
||||
ImGui_ImplWGPU_InvalidateDeviceObjects();
|
||||
|
||||
// Create render pipeline
|
||||
WGPURenderPipelineDescriptor graphics_pipeline_desc = {};
|
||||
graphics_pipeline_desc.primitive.topology = WGPUPrimitiveTopology_TriangleList;
|
||||
graphics_pipeline_desc.primitive.stripIndexFormat = WGPUIndexFormat_Undefined;
|
||||
graphics_pipeline_desc.primitive.frontFace = WGPUFrontFace_CW;
|
||||
graphics_pipeline_desc.primitive.cullMode = WGPUCullMode_None;
|
||||
graphics_pipeline_desc.multisample = bd->initInfo.PipelineMultisampleState;
|
||||
|
||||
// Bind group layouts
|
||||
WGPUBindGroupLayoutEntry common_bg_layout_entries[2] = {};
|
||||
common_bg_layout_entries[0].binding = 0;
|
||||
common_bg_layout_entries[0].visibility = WGPUShaderStage_Vertex | WGPUShaderStage_Fragment;
|
||||
common_bg_layout_entries[0].buffer.type = WGPUBufferBindingType_Uniform;
|
||||
common_bg_layout_entries[1].binding = 1;
|
||||
common_bg_layout_entries[1].visibility = WGPUShaderStage_Fragment;
|
||||
common_bg_layout_entries[1].sampler.type = WGPUSamplerBindingType_Filtering;
|
||||
|
||||
WGPUBindGroupLayoutEntry image_bg_layout_entries[1] = {};
|
||||
image_bg_layout_entries[0].binding = 0;
|
||||
image_bg_layout_entries[0].visibility = WGPUShaderStage_Fragment;
|
||||
image_bg_layout_entries[0].texture.sampleType = WGPUTextureSampleType_Float;
|
||||
image_bg_layout_entries[0].texture.viewDimension = WGPUTextureViewDimension_2D;
|
||||
|
||||
WGPUBindGroupLayoutDescriptor common_bg_layout_desc = {};
|
||||
common_bg_layout_desc.entryCount = 2;
|
||||
common_bg_layout_desc.entries = common_bg_layout_entries;
|
||||
|
||||
WGPUBindGroupLayoutDescriptor image_bg_layout_desc = {};
|
||||
image_bg_layout_desc.entryCount = 1;
|
||||
image_bg_layout_desc.entries = image_bg_layout_entries;
|
||||
|
||||
WGPUBindGroupLayout bg_layouts[2];
|
||||
bg_layouts[0] = wgpuDeviceCreateBindGroupLayout(bd->wgpuDevice, &common_bg_layout_desc);
|
||||
bg_layouts[1] = wgpuDeviceCreateBindGroupLayout(bd->wgpuDevice, &image_bg_layout_desc);
|
||||
|
||||
WGPUPipelineLayoutDescriptor layout_desc = {};
|
||||
layout_desc.bindGroupLayoutCount = 2;
|
||||
layout_desc.bindGroupLayouts = bg_layouts;
|
||||
graphics_pipeline_desc.layout = wgpuDeviceCreatePipelineLayout(bd->wgpuDevice, &layout_desc);
|
||||
|
||||
// Create the vertex shader
|
||||
WGPUProgrammableStageDescriptor vertex_shader_desc = ImGui_ImplWGPU_CreateShaderModule(__shader_vert_wgsl);
|
||||
graphics_pipeline_desc.vertex.module = vertex_shader_desc.module;
|
||||
graphics_pipeline_desc.vertex.entryPoint = vertex_shader_desc.entryPoint;
|
||||
|
||||
// Vertex input configuration
|
||||
WGPUVertexAttribute attribute_desc[] =
|
||||
{
|
||||
{ WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, pos), 0 },
|
||||
{ WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, uv), 1 },
|
||||
{ WGPUVertexFormat_Unorm8x4, (uint64_t)offsetof(ImDrawVert, col), 2 },
|
||||
};
|
||||
|
||||
WGPUVertexBufferLayout buffer_layouts[1];
|
||||
buffer_layouts[0].arrayStride = sizeof(ImDrawVert);
|
||||
buffer_layouts[0].stepMode = WGPUVertexStepMode_Vertex;
|
||||
buffer_layouts[0].attributeCount = 3;
|
||||
buffer_layouts[0].attributes = attribute_desc;
|
||||
|
||||
graphics_pipeline_desc.vertex.bufferCount = 1;
|
||||
graphics_pipeline_desc.vertex.buffers = buffer_layouts;
|
||||
|
||||
// Create the pixel shader
|
||||
WGPUProgrammableStageDescriptor pixel_shader_desc = ImGui_ImplWGPU_CreateShaderModule(__shader_frag_wgsl);
|
||||
|
||||
// Create the blending setup
|
||||
WGPUBlendState blend_state = {};
|
||||
blend_state.alpha.operation = WGPUBlendOperation_Add;
|
||||
blend_state.alpha.srcFactor = WGPUBlendFactor_One;
|
||||
blend_state.alpha.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha;
|
||||
blend_state.color.operation = WGPUBlendOperation_Add;
|
||||
blend_state.color.srcFactor = WGPUBlendFactor_SrcAlpha;
|
||||
blend_state.color.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha;
|
||||
|
||||
WGPUColorTargetState color_state = {};
|
||||
color_state.format = bd->renderTargetFormat;
|
||||
color_state.blend = &blend_state;
|
||||
color_state.writeMask = WGPUColorWriteMask_All;
|
||||
|
||||
WGPUFragmentState fragment_state = {};
|
||||
fragment_state.module = pixel_shader_desc.module;
|
||||
fragment_state.entryPoint = pixel_shader_desc.entryPoint;
|
||||
fragment_state.targetCount = 1;
|
||||
fragment_state.targets = &color_state;
|
||||
|
||||
graphics_pipeline_desc.fragment = &fragment_state;
|
||||
|
||||
// Create depth-stencil State
|
||||
WGPUDepthStencilState depth_stencil_state = {};
|
||||
depth_stencil_state.format = bd->depthStencilFormat;
|
||||
#ifdef IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
depth_stencil_state.depthWriteEnabled = WGPUOptionalBool_False;
|
||||
#else
|
||||
depth_stencil_state.depthWriteEnabled = false;
|
||||
#endif
|
||||
depth_stencil_state.depthCompare = WGPUCompareFunction_Always;
|
||||
depth_stencil_state.stencilFront.compare = WGPUCompareFunction_Always;
|
||||
depth_stencil_state.stencilFront.failOp = WGPUStencilOperation_Keep;
|
||||
depth_stencil_state.stencilFront.depthFailOp = WGPUStencilOperation_Keep;
|
||||
depth_stencil_state.stencilFront.passOp = WGPUStencilOperation_Keep;
|
||||
depth_stencil_state.stencilBack.compare = WGPUCompareFunction_Always;
|
||||
depth_stencil_state.stencilBack.failOp = WGPUStencilOperation_Keep;
|
||||
depth_stencil_state.stencilBack.depthFailOp = WGPUStencilOperation_Keep;
|
||||
depth_stencil_state.stencilBack.passOp = WGPUStencilOperation_Keep;
|
||||
|
||||
// Configure disabled depth-stencil state
|
||||
graphics_pipeline_desc.depthStencil = (bd->depthStencilFormat == WGPUTextureFormat_Undefined) ? nullptr : &depth_stencil_state;
|
||||
|
||||
bd->pipelineState = wgpuDeviceCreateRenderPipeline(bd->wgpuDevice, &graphics_pipeline_desc);
|
||||
|
||||
ImGui_ImplWGPU_CreateFontsTexture();
|
||||
ImGui_ImplWGPU_CreateUniformBuffer();
|
||||
|
||||
// Create resource bind group
|
||||
WGPUBindGroupEntry common_bg_entries[] =
|
||||
{
|
||||
{ nullptr, 0, bd->renderResources.Uniforms, 0, MEMALIGN(sizeof(Uniforms), 16), 0, 0 },
|
||||
{ nullptr, 1, 0, 0, 0, bd->renderResources.Sampler, 0 },
|
||||
};
|
||||
|
||||
WGPUBindGroupDescriptor common_bg_descriptor = {};
|
||||
common_bg_descriptor.layout = bg_layouts[0];
|
||||
common_bg_descriptor.entryCount = sizeof(common_bg_entries) / sizeof(WGPUBindGroupEntry);
|
||||
common_bg_descriptor.entries = common_bg_entries;
|
||||
bd->renderResources.CommonBindGroup = wgpuDeviceCreateBindGroup(bd->wgpuDevice, &common_bg_descriptor);
|
||||
|
||||
WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(bg_layouts[1], bd->renderResources.FontTextureView);
|
||||
bd->renderResources.ImageBindGroup = image_bind_group;
|
||||
bd->renderResources.ImageBindGroupLayout = bg_layouts[1];
|
||||
bd->renderResources.ImageBindGroups.SetVoidPtr(ImHashData(&bd->renderResources.FontTextureView, sizeof(ImTextureID)), image_bind_group);
|
||||
|
||||
SafeRelease(vertex_shader_desc.module);
|
||||
SafeRelease(pixel_shader_desc.module);
|
||||
SafeRelease(graphics_pipeline_desc.layout);
|
||||
SafeRelease(bg_layouts[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplWGPU_InvalidateDeviceObjects()
|
||||
{
|
||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||
if (!bd->wgpuDevice)
|
||||
return;
|
||||
|
||||
SafeRelease(bd->pipelineState);
|
||||
SafeRelease(bd->renderResources);
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.Fonts->SetTexID(0); // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
|
||||
for (unsigned int i = 0; i < bd->numFramesInFlight; i++)
|
||||
SafeRelease(bd->pFrameResources[i]);
|
||||
}
|
||||
|
||||
bool ImGui_ImplWGPU_Init(ImGui_ImplWGPU_InitInfo* init_info)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplWGPU_Data* bd = IM_NEW(ImGui_ImplWGPU_Data)();
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
io.BackendRendererName = "imgui_impl_webgpu_emscripten";
|
||||
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
||||
io.BackendRendererName = "imgui_impl_webgpu_dawn";
|
||||
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
io.BackendRendererName = "imgui_impl_webgpu_wgpu";
|
||||
#else
|
||||
io.BackendRendererName = "imgui_impl_webgpu";
|
||||
#endif
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
|
||||
bd->initInfo = *init_info;
|
||||
bd->wgpuDevice = init_info->Device;
|
||||
bd->defaultQueue = wgpuDeviceGetQueue(bd->wgpuDevice);
|
||||
bd->renderTargetFormat = init_info->RenderTargetFormat;
|
||||
bd->depthStencilFormat = init_info->DepthStencilFormat;
|
||||
bd->numFramesInFlight = init_info->NumFramesInFlight;
|
||||
bd->frameIndex = UINT_MAX;
|
||||
|
||||
bd->renderResources.FontTexture = nullptr;
|
||||
bd->renderResources.FontTextureView = nullptr;
|
||||
bd->renderResources.Sampler = nullptr;
|
||||
bd->renderResources.Uniforms = nullptr;
|
||||
bd->renderResources.CommonBindGroup = nullptr;
|
||||
bd->renderResources.ImageBindGroups.Data.reserve(100);
|
||||
bd->renderResources.ImageBindGroup = nullptr;
|
||||
bd->renderResources.ImageBindGroupLayout = nullptr;
|
||||
|
||||
// Create buffers with a default size (they will later be grown as needed)
|
||||
bd->pFrameResources = new FrameResources[bd->numFramesInFlight];
|
||||
for (unsigned int i = 0; i < bd->numFramesInFlight; i++)
|
||||
{
|
||||
FrameResources* fr = &bd->pFrameResources[i];
|
||||
fr->IndexBuffer = nullptr;
|
||||
fr->VertexBuffer = nullptr;
|
||||
fr->IndexBufferHost = nullptr;
|
||||
fr->VertexBufferHost = nullptr;
|
||||
fr->IndexBufferSize = 10000;
|
||||
fr->VertexBufferSize = 5000;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplWGPU_Shutdown()
|
||||
{
|
||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplWGPU_InvalidateDeviceObjects();
|
||||
delete[] bd->pFrameResources;
|
||||
bd->pFrameResources = nullptr;
|
||||
wgpuQueueRelease(bd->defaultQueue);
|
||||
bd->wgpuDevice = nullptr;
|
||||
bd->numFramesInFlight = 0;
|
||||
bd->frameIndex = UINT_MAX;
|
||||
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
void ImGui_ImplWGPU_NewFrame()
|
||||
{
|
||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||
if (!bd->pipelineState)
|
||||
ImGui_ImplWGPU_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
// dear imgui: Renderer for WebGPU
|
||||
// This needs to be used along with a Platform Binding (e.g. GLFW)
|
||||
// (Please note that WebGPU is currently experimental, will not run on non-beta browsers, and may break.)
|
||||
|
||||
// Important note to dawn and/or wgpu users: when targeting native platforms (i.e. NOT emscripten),
|
||||
// one of IMGUI_IMPL_WEBGPU_BACKEND_DAWN or IMGUI_IMPL_WEBGPU_BACKEND_WGPU must be provided.
|
||||
// Add #define to your imconfig.h file, or as a compilation flag in your build system.
|
||||
// This requirement will be removed once WebGPU stabilizes and backends converge on a unified interface.
|
||||
//#define IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
//#define IMGUI_IMPL_WEBGPU_BACKEND_WGPU
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows). Not meaningful on the web.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
#include <webgpu/webgpu.h>
|
||||
|
||||
// Initialization data, for ImGui_ImplWGPU_Init()
|
||||
struct ImGui_ImplWGPU_InitInfo
|
||||
{
|
||||
WGPUDevice Device;
|
||||
int NumFramesInFlight = 3;
|
||||
WGPUTextureFormat RenderTargetFormat = WGPUTextureFormat_Undefined;
|
||||
WGPUTextureFormat DepthStencilFormat = WGPUTextureFormat_Undefined;
|
||||
WGPUMultisampleState PipelineMultisampleState = {};
|
||||
|
||||
ImGui_ImplWGPU_InitInfo()
|
||||
{
|
||||
PipelineMultisampleState.count = 1;
|
||||
PipelineMultisampleState.mask = UINT32_MAX;
|
||||
PipelineMultisampleState.alphaToCoverageEnabled = false;
|
||||
}
|
||||
};
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplWGPU_Init(ImGui_ImplWGPU_InitInfo* init_info);
|
||||
IMGUI_IMPL_API void ImGui_ImplWGPU_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplWGPU_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder);
|
||||
|
||||
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||
IMGUI_IMPL_API bool ImGui_ImplWGPU_CreateDeviceObjects();
|
||||
IMGUI_IMPL_API void ImGui_ImplWGPU_InvalidateDeviceObjects();
|
||||
|
||||
// [BETA] Selected render state data shared with callbacks.
|
||||
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplWGPU_RenderDrawData() call.
|
||||
// (Please open an issue if you feel you need access to more data)
|
||||
struct ImGui_ImplWGPU_RenderState
|
||||
{
|
||||
WGPUDevice Device;
|
||||
WGPURenderPassEncoder RenderPassEncoder;
|
||||
};
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
+342
-172
@@ -4,39 +4,33 @@
|
||||
// Implemented features:
|
||||
// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_win32.h"
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <windowsx.h> // GET_X_LPARAM(), GET_Y_LPARAM()
|
||||
#include <tchar.h>
|
||||
#include <dwmapi.h>
|
||||
|
||||
// Configuration flags to add in your imconfig.h file:
|
||||
// Configuration flags to add in your imconfig file:
|
||||
//#define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD // Disable gamepad support. This was meaningful before <1.81 but we now load XInput dynamically so the option is now less relevant.
|
||||
|
||||
// Using XInput for gamepad (will load DLL dynamically)
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
#include <xinput.h>
|
||||
typedef DWORD (WINAPI *PFN_XInputGetCapabilities)(DWORD, DWORD, XINPUT_CAPABILITIES*);
|
||||
typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
|
||||
#endif
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2023-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2024-11-21: [Docking] Fixed a crash when multiple processes are running with multi-viewports, caused by misusage of GetProp(). (#8162, #8069)
|
||||
// 2024-10-28: [Docking] Rely on property stored inside HWND to retrieve context/viewport, should facilitate attempt to use this for parallel contexts. (#8069)
|
||||
// 2024-09-16: [Docking] Inputs: fixed an issue where a viewport destroyed while clicking would hog mouse tracking and temporary lead to incorrect update of HoveredWindow. (#7971)
|
||||
// 2024-07-08: Inputs: Fixed ImGuiMod_Super being mapped to VK_APPS instead of VK_LWIN||VK_RWIN. (#7768)
|
||||
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys.
|
||||
// 2023-09-25: Inputs: Synthesize key-down event on key-up for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows doesn't emit it (same behavior as GLFW/SDL).
|
||||
// 2023-09-07: Inputs: Added support for keyboard codepage conversion for when application is compiled in MBCS mode and using a non-Unicode window.
|
||||
// 2023-04-19: Added ImGui_ImplWin32_InitForOpenGL() to facilitate combining raw Win32/Winapi with OpenGL. (#3218)
|
||||
// 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen/ImGuiMouseSource_Pen. (#2702)
|
||||
// 2023-02-15: Inputs: Use WM_NCMOUSEMOVE / WM_NCMOUSELEAVE to track mouse position over non-client area (e.g. OS decorations) when app is not focused. (#6045, #6162)
|
||||
// 2023-02-02: Inputs: Flipping WM_MOUSEHWHEEL (horizontal mouse-wheel) value to match other backends and offer consistent horizontal scrolling direction. (#4019, #6096, #1463)
|
||||
@@ -85,20 +79,50 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
|
||||
// 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging.
|
||||
// 2016-11-12: Inputs: Only call Win32 ::SetCursor(nullptr) when io.MouseDrawCursor is set.
|
||||
|
||||
#include "imgui.h"
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui_impl_win32.h"
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <windowsx.h> // GET_X_LPARAM(), GET_Y_LPARAM()
|
||||
#include <tchar.h>
|
||||
#include <dwmapi.h>
|
||||
|
||||
// Using XInput for gamepad (will load DLL dynamically)
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
#include <xinput.h>
|
||||
typedef DWORD(WINAPI* PFN_XInputGetCapabilities)(DWORD, DWORD, XINPUT_CAPABILITIES*);
|
||||
typedef DWORD(WINAPI* PFN_XInputGetState)(DWORD, XINPUT_STATE*);
|
||||
#endif
|
||||
|
||||
// Clang/GCC warnings with -Weverything
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wcast-function-type" // warning: cast between incompatible function types (for loader)
|
||||
#endif
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||||
#pragma GCC diagnostic ignored "-Wcast-function-type" // warning: cast between incompatible function types (for loader)
|
||||
#endif
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplWin32_InitPlatformInterface();
|
||||
static void ImGui_ImplWin32_ShutdownPlatformInterface();
|
||||
static void ImGui_ImplWin32_InitMultiViewportSupport(bool platform_has_own_dc);
|
||||
static void ImGui_ImplWin32_ShutdownMultiViewportSupport();
|
||||
static void ImGui_ImplWin32_UpdateMonitors();
|
||||
|
||||
struct ImGui_ImplWin32_Data
|
||||
{
|
||||
HWND hWnd;
|
||||
HWND MouseHwnd;
|
||||
int MouseTrackedArea; // 0: not tracked, 1: client are, 2: non-client area
|
||||
int MouseTrackedArea; // 0: not tracked, 1: client area, 2: non-client area
|
||||
int MouseButtonsDown;
|
||||
INT64 Time;
|
||||
INT64 TicksPerSecond;
|
||||
ImGuiMouseCursor LastMouseCursor;
|
||||
UINT32 KeyboardCodePage;
|
||||
bool WantUpdateMonitors;
|
||||
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
@@ -120,11 +144,26 @@ static ImGui_ImplWin32_Data* ImGui_ImplWin32_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplWin32_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
|
||||
}
|
||||
static ImGui_ImplWin32_Data* ImGui_ImplWin32_GetBackendData(ImGuiIO& io)
|
||||
{
|
||||
return (ImGui_ImplWin32_Data*)io.BackendPlatformUserData;
|
||||
}
|
||||
|
||||
// Functions
|
||||
bool ImGui_ImplWin32_Init(void* hwnd)
|
||||
static void ImGui_ImplWin32_UpdateKeyboardCodePage(ImGuiIO& io)
|
||||
{
|
||||
// Retrieve keyboard code page, required for handling of non-Unicode Windows.
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(io);
|
||||
HKL keyboard_layout = ::GetKeyboardLayout(0);
|
||||
LCID keyboard_lcid = MAKELCID(HIWORD(keyboard_layout), SORT_DEFAULT);
|
||||
if (::GetLocaleInfoA(keyboard_lcid, (LOCALE_RETURN_NUMBER | LOCALE_IDEFAULTANSICODEPAGE), (LPSTR)&bd->KeyboardCodePage, sizeof(bd->KeyboardCodePage)) == 0)
|
||||
bd->KeyboardCodePage = CP_ACP; // Fallback to default ANSI code page when fails.
|
||||
}
|
||||
|
||||
static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IMGUI_CHECKVERSION();
|
||||
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
|
||||
|
||||
INT64 perf_frequency, perf_counter;
|
||||
@@ -143,16 +182,22 @@ bool ImGui_ImplWin32_Init(void* hwnd)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional)
|
||||
|
||||
bd->hWnd = (HWND)hwnd;
|
||||
bd->WantUpdateMonitors = true;
|
||||
bd->TicksPerSecond = perf_frequency;
|
||||
bd->Time = perf_counter;
|
||||
bd->LastMouseCursor = ImGuiMouseCursor_COUNT;
|
||||
ImGui_ImplWin32_UpdateKeyboardCodePage(io);
|
||||
|
||||
// Update monitor a first time during init
|
||||
ImGui_ImplWin32_UpdateMonitors();
|
||||
|
||||
// Our mouse update function expect PlatformHandle to be filled for the main viewport
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (void*)bd->hWnd;
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplWin32_InitPlatformInterface();
|
||||
|
||||
// Be aware that GetPropA()/SetPropA() may be accessed from other processes.
|
||||
// So as we store a pointer in IMGUI_CONTEXT we need to make sure we only call GetPropA() on windows owned by our process.
|
||||
::SetPropA(bd->hWnd, "IMGUI_CONTEXT", ImGui::GetCurrentContext());
|
||||
ImGui_ImplWin32_InitMultiViewportSupport(platform_has_own_dc);
|
||||
|
||||
// Dynamically load XInput library
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
@@ -178,13 +223,25 @@ bool ImGui_ImplWin32_Init(void* hwnd)
|
||||
return true;
|
||||
}
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd)
|
||||
{
|
||||
return ImGui_ImplWin32_InitEx(hwnd, false);
|
||||
}
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_ImplWin32_InitForOpenGL(void* hwnd)
|
||||
{
|
||||
// OpenGL needs CS_OWNDC
|
||||
return ImGui_ImplWin32_InitEx(hwnd, true);
|
||||
}
|
||||
|
||||
void ImGui_ImplWin32_Shutdown()
|
||||
{
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplWin32_ShutdownPlatformInterface();
|
||||
::SetPropA(bd->hWnd, "IMGUI_CONTEXT", nullptr);
|
||||
ImGui_ImplWin32_ShutdownMultiViewportSupport();
|
||||
|
||||
// Unload XInput library
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
@@ -194,16 +251,15 @@ void ImGui_ImplWin32_Shutdown()
|
||||
|
||||
io.BackendPlatformName = nullptr;
|
||||
io.BackendPlatformUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport);
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
static bool ImGui_ImplWin32_UpdateMouseCursor()
|
||||
static bool ImGui_ImplWin32_UpdateMouseCursor(ImGuiIO& io, ImGuiMouseCursor imgui_cursor)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
|
||||
return false;
|
||||
|
||||
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
||||
if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
|
||||
{
|
||||
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
|
||||
@@ -235,54 +291,62 @@ static bool IsVkDown(int vk)
|
||||
return (::GetKeyState(vk) & 0x8000) != 0;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_AddKeyEvent(ImGuiKey key, bool down, int native_keycode, int native_scancode = -1)
|
||||
static void ImGui_ImplWin32_AddKeyEvent(ImGuiIO& io, ImGuiKey key, bool down, int native_keycode, int native_scancode = -1)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.AddKeyEvent(key, down);
|
||||
io.SetKeyEventNativeData(key, native_keycode, native_scancode); // To support legacy indexing (<1.87 user code)
|
||||
IM_UNUSED(native_scancode);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_ProcessKeyEventsWorkarounds()
|
||||
static void ImGui_ImplWin32_ProcessKeyEventsWorkarounds(ImGuiIO& io)
|
||||
{
|
||||
// Left & right Shift keys: when both are pressed together, Windows tend to not generate the WM_KEYUP event for the first released one.
|
||||
if (ImGui::IsKeyDown(ImGuiKey_LeftShift) && !IsVkDown(VK_LSHIFT))
|
||||
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftShift, false, VK_LSHIFT);
|
||||
ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_LeftShift, false, VK_LSHIFT);
|
||||
if (ImGui::IsKeyDown(ImGuiKey_RightShift) && !IsVkDown(VK_RSHIFT))
|
||||
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightShift, false, VK_RSHIFT);
|
||||
ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_RightShift, false, VK_RSHIFT);
|
||||
|
||||
// Sometimes WM_KEYUP for Win key is not passed down to the app (e.g. for Win+V on some setups, according to GLFW).
|
||||
if (ImGui::IsKeyDown(ImGuiKey_LeftSuper) && !IsVkDown(VK_LWIN))
|
||||
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftSuper, false, VK_LWIN);
|
||||
ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_LeftSuper, false, VK_LWIN);
|
||||
if (ImGui::IsKeyDown(ImGuiKey_RightSuper) && !IsVkDown(VK_RWIN))
|
||||
ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightSuper, false, VK_RWIN);
|
||||
ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_RightSuper, false, VK_RWIN);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_UpdateKeyModifiers()
|
||||
static void ImGui_ImplWin32_UpdateKeyModifiers(ImGuiIO& io)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.AddKeyEvent(ImGuiMod_Ctrl, IsVkDown(VK_CONTROL));
|
||||
io.AddKeyEvent(ImGuiMod_Shift, IsVkDown(VK_SHIFT));
|
||||
io.AddKeyEvent(ImGuiMod_Alt, IsVkDown(VK_MENU));
|
||||
io.AddKeyEvent(ImGuiMod_Super, IsVkDown(VK_APPS));
|
||||
io.AddKeyEvent(ImGuiMod_Super, IsVkDown(VK_LWIN) || IsVkDown(VK_RWIN));
|
||||
}
|
||||
|
||||
static ImGuiViewport* ImGui_ImplWin32_FindViewportByPlatformHandle(ImGuiPlatformIO& platform_io, HWND hwnd)
|
||||
{
|
||||
// We cannot use ImGui::FindViewportByPlatformHandle() because it doesn't take a context.
|
||||
// When called from ImGui_ImplWin32_WndProcHandler_PlatformWindow() we don't assume that context is bound.
|
||||
//return ImGui::FindViewportByPlatformHandle((void*)hwnd);
|
||||
for (ImGuiViewport* viewport : platform_io.Viewports)
|
||||
if (viewport->PlatformHandle == hwnd)
|
||||
return viewport;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// This code supports multi-viewports (multiple OS Windows mapped into different Dear ImGui viewports)
|
||||
// Because of that, it is a little more complicated than your typical single-viewport binding code!
|
||||
static void ImGui_ImplWin32_UpdateMouseData()
|
||||
static void ImGui_ImplWin32_UpdateMouseData(ImGuiIO& io, ImGuiPlatformIO& platform_io)
|
||||
{
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(io);
|
||||
IM_ASSERT(bd->hWnd != 0);
|
||||
|
||||
POINT mouse_screen_pos;
|
||||
bool has_mouse_screen_pos = ::GetCursorPos(&mouse_screen_pos) != 0;
|
||||
|
||||
HWND focused_window = ::GetForegroundWindow();
|
||||
const bool is_app_focused = (focused_window && (focused_window == bd->hWnd || ::IsChild(focused_window, bd->hWnd) || ImGui::FindViewportByPlatformHandle((void*)focused_window)));
|
||||
const bool is_app_focused = (focused_window && (focused_window == bd->hWnd || ::IsChild(focused_window, bd->hWnd) || ImGui_ImplWin32_FindViewportByPlatformHandle(platform_io, focused_window)));
|
||||
if (is_app_focused)
|
||||
{
|
||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
|
||||
// When multi-viewports are enabled, all Dear ImGui positions are same as OS positions.
|
||||
if (io.WantSetMousePos)
|
||||
{
|
||||
@@ -317,17 +381,16 @@ static void ImGui_ImplWin32_UpdateMouseData()
|
||||
ImGuiID mouse_viewport_id = 0;
|
||||
if (has_mouse_screen_pos)
|
||||
if (HWND hovered_hwnd = ::WindowFromPoint(mouse_screen_pos))
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hovered_hwnd))
|
||||
if (ImGuiViewport* viewport = ImGui_ImplWin32_FindViewportByPlatformHandle(platform_io, hovered_hwnd))
|
||||
mouse_viewport_id = viewport->ID;
|
||||
io.AddMouseViewportEvent(mouse_viewport_id);
|
||||
}
|
||||
|
||||
// Gamepad navigation mapping
|
||||
static void ImGui_ImplWin32_UpdateGamepads()
|
||||
static void ImGui_ImplWin32_UpdateGamepads(ImGuiIO& io)
|
||||
{
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(io);
|
||||
//if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) // FIXME: Technically feeding gamepad shouldn't depend on this now that they are regular inputs.
|
||||
// return;
|
||||
|
||||
@@ -376,7 +439,9 @@ static void ImGui_ImplWin32_UpdateGamepads()
|
||||
MAP_ANALOG(ImGuiKey_GamepadRStickDown, gamepad.sThumbRY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
|
||||
#undef MAP_BUTTON
|
||||
#undef MAP_ANALOG
|
||||
#endif // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
#else // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
IM_UNUSED(io);
|
||||
#endif
|
||||
}
|
||||
|
||||
static BOOL CALLBACK ImGui_ImplWin32_UpdateMonitors_EnumFunc(HMONITOR monitor, HDC, LPRECT, LPARAM)
|
||||
@@ -391,6 +456,9 @@ static BOOL CALLBACK ImGui_ImplWin32_UpdateMonitors_EnumFunc(HMONITOR monitor, H
|
||||
imgui_monitor.WorkPos = ImVec2((float)info.rcWork.left, (float)info.rcWork.top);
|
||||
imgui_monitor.WorkSize = ImVec2((float)(info.rcWork.right - info.rcWork.left), (float)(info.rcWork.bottom - info.rcWork.top));
|
||||
imgui_monitor.DpiScale = ImGui_ImplWin32_GetDpiScaleForMonitor(monitor);
|
||||
imgui_monitor.PlatformHandle = (void*)monitor;
|
||||
if (imgui_monitor.DpiScale <= 0.0f)
|
||||
return TRUE; // Some accessibility applications are declaring virtual monitors with a DPI of 0, see #7902.
|
||||
ImGuiPlatformIO& io = ImGui::GetPlatformIO();
|
||||
if (info.dwFlags & MONITORINFOF_PRIMARY)
|
||||
io.Monitors.push_front(imgui_monitor);
|
||||
@@ -409,9 +477,10 @@ static void ImGui_ImplWin32_UpdateMonitors()
|
||||
|
||||
void ImGui_ImplWin32_NewFrame()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplWin32_Init()?");
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized? Did you call ImGui_ImplWin32_Init()?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
// Setup display size (every frame to accommodate for window resizing)
|
||||
RECT rect = { 0, 0, 0, 0 };
|
||||
@@ -427,29 +496,32 @@ void ImGui_ImplWin32_NewFrame()
|
||||
bd->Time = current_time;
|
||||
|
||||
// Update OS mouse position
|
||||
ImGui_ImplWin32_UpdateMouseData();
|
||||
ImGui_ImplWin32_UpdateMouseData(io, platform_io);
|
||||
|
||||
// Process workarounds for known Windows key handling issues
|
||||
ImGui_ImplWin32_ProcessKeyEventsWorkarounds();
|
||||
ImGui_ImplWin32_ProcessKeyEventsWorkarounds(io);
|
||||
|
||||
// Update OS mouse cursor with the cursor requested by imgui
|
||||
ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor();
|
||||
if (bd->LastMouseCursor != mouse_cursor)
|
||||
{
|
||||
bd->LastMouseCursor = mouse_cursor;
|
||||
ImGui_ImplWin32_UpdateMouseCursor();
|
||||
ImGui_ImplWin32_UpdateMouseCursor(io, mouse_cursor);
|
||||
}
|
||||
|
||||
// Update game controllers (if enabled and available)
|
||||
ImGui_ImplWin32_UpdateGamepads();
|
||||
ImGui_ImplWin32_UpdateGamepads(io);
|
||||
}
|
||||
|
||||
// There is no distinct VK_xxx for keypad enter, instead it is VK_RETURN + KF_EXTENDED, we assign it an arbitrary value to make code more readable (VK_ codes go up to 255)
|
||||
#define IM_VK_KEYPAD_ENTER (VK_RETURN + 256)
|
||||
|
||||
// Map VK_xxx to ImGuiKey_xxx.
|
||||
static ImGuiKey ImGui_ImplWin32_VirtualKeyToImGuiKey(WPARAM wParam)
|
||||
// Not static to allow third-party code to use that if they want to (but undocumented)
|
||||
ImGuiKey ImGui_ImplWin32_KeyEventToImGuiKey(WPARAM wParam, LPARAM lParam);
|
||||
ImGuiKey ImGui_ImplWin32_KeyEventToImGuiKey(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// There is no distinct VK_xxx for keypad enter, instead it is VK_RETURN + KF_EXTENDED.
|
||||
if ((wParam == VK_RETURN) && (HIWORD(lParam) & KF_EXTENDED))
|
||||
return ImGuiKey_KeypadEnter;
|
||||
|
||||
switch (wParam)
|
||||
{
|
||||
case VK_TAB: return ImGuiKey_Tab;
|
||||
@@ -498,7 +570,6 @@ static ImGuiKey ImGui_ImplWin32_VirtualKeyToImGuiKey(WPARAM wParam)
|
||||
case VK_MULTIPLY: return ImGuiKey_KeypadMultiply;
|
||||
case VK_SUBTRACT: return ImGuiKey_KeypadSubtract;
|
||||
case VK_ADD: return ImGuiKey_KeypadAdd;
|
||||
case IM_VK_KEYPAD_ENTER: return ImGuiKey_KeypadEnter;
|
||||
case VK_LSHIFT: return ImGuiKey_LeftShift;
|
||||
case VK_LCONTROL: return ImGuiKey_LeftCtrl;
|
||||
case VK_LMENU: return ImGuiKey_LeftAlt;
|
||||
@@ -556,6 +627,20 @@ static ImGuiKey ImGui_ImplWin32_VirtualKeyToImGuiKey(WPARAM wParam)
|
||||
case VK_F10: return ImGuiKey_F10;
|
||||
case VK_F11: return ImGuiKey_F11;
|
||||
case VK_F12: return ImGuiKey_F12;
|
||||
case VK_F13: return ImGuiKey_F13;
|
||||
case VK_F14: return ImGuiKey_F14;
|
||||
case VK_F15: return ImGuiKey_F15;
|
||||
case VK_F16: return ImGuiKey_F16;
|
||||
case VK_F17: return ImGuiKey_F17;
|
||||
case VK_F18: return ImGuiKey_F18;
|
||||
case VK_F19: return ImGuiKey_F19;
|
||||
case VK_F20: return ImGuiKey_F20;
|
||||
case VK_F21: return ImGuiKey_F21;
|
||||
case VK_F22: return ImGuiKey_F22;
|
||||
case VK_F23: return ImGuiKey_F23;
|
||||
case VK_F24: return ImGuiKey_F24;
|
||||
case VK_BROWSER_BACK: return ImGuiKey_AppBack;
|
||||
case VK_BROWSER_FORWARD: return ImGuiKey_AppForward;
|
||||
default: return ImGuiKey_None;
|
||||
}
|
||||
}
|
||||
@@ -568,22 +653,10 @@ static ImGuiKey ImGui_ImplWin32_VirtualKeyToImGuiKey(WPARAM wParam)
|
||||
#define DBT_DEVNODES_CHANGED 0x0007
|
||||
#endif
|
||||
|
||||
// Win32 message handler (process Win32 mouse/keyboard inputs, etc.)
|
||||
// Call from your application's message handler. Keep calling your message handler unless this function returns TRUE.
|
||||
// When implementing your own backend, you can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if Dear ImGui wants to use your inputs.
|
||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
|
||||
// Generally you may always pass all inputs to Dear ImGui, and hide them from your application based on those two flags.
|
||||
// PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinates when dragging mouse outside of our window bounds.
|
||||
// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag.
|
||||
#if 0
|
||||
// Copy this line into your .cpp file to forward declare the function.
|
||||
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
#endif
|
||||
|
||||
// Helper to obtain the source of mouse messages.
|
||||
// See https://learn.microsoft.com/en-us/windows/win32/tablet/system-events-and-mouse-messages
|
||||
// Prefer to call this at the top of the message handler to avoid the possibility of other Win32 calls interfering with this.
|
||||
static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
|
||||
static ImGuiMouseSource ImGui_ImplWin32_GetMouseSourceFromMessageExtraInfo()
|
||||
{
|
||||
LPARAM extra_info = ::GetMessageExtraInfo();
|
||||
if ((extra_info & 0xFFFFFF80) == 0xFF515700)
|
||||
@@ -593,21 +666,40 @@ static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
|
||||
return ImGuiMouseSource_Mouse;
|
||||
}
|
||||
|
||||
// Win32 message handler (process Win32 mouse/keyboard inputs, etc.)
|
||||
// Call from your application's message handler. Keep calling your message handler unless this function returns TRUE.
|
||||
// When implementing your own backend, you can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if Dear ImGui wants to use your inputs.
|
||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
|
||||
// Generally you may always pass all inputs to Dear ImGui, and hide them from your application based on those two flags.
|
||||
// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag.
|
||||
|
||||
// Copy either line into your .cpp file to forward declare the function:
|
||||
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); // Use ImGui::GetCurrentContext()
|
||||
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandlerEx(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, ImGuiIO& io); // Doesn't use ImGui::GetCurrentContext()
|
||||
|
||||
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// Most backends don't have silent checks like this one, but we need it because WndProc are called early in CreateWindow().
|
||||
// We silently allow both context or just only backend data to be nullptr.
|
||||
if (ImGui::GetCurrentContext() == nullptr)
|
||||
return 0;
|
||||
return ImGui_ImplWin32_WndProcHandlerEx(hwnd, msg, wParam, lParam, ImGui::GetIO());
|
||||
}
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
|
||||
// This version is in theory thread-safe in the sense that no path should access ImGui::GetCurrentContext().
|
||||
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandlerEx(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, ImGuiIO& io)
|
||||
{
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(io);
|
||||
if (bd == nullptr)
|
||||
return 0;
|
||||
switch (msg)
|
||||
{
|
||||
case WM_MOUSEMOVE:
|
||||
case WM_NCMOUSEMOVE:
|
||||
{
|
||||
// We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE events
|
||||
ImGuiMouseSource mouse_source = GetMouseSourceFromMessageExtraInfo();
|
||||
ImGuiMouseSource mouse_source = ImGui_ImplWin32_GetMouseSourceFromMessageExtraInfo();
|
||||
const int area = (msg == WM_MOUSEMOVE) ? 1 : 2;
|
||||
bd->MouseHwnd = hwnd;
|
||||
if (bd->MouseTrackedArea != area)
|
||||
@@ -627,7 +719,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
||||
::ScreenToClient(hwnd, &mouse_pos);
|
||||
io.AddMouseSourceEvent(mouse_source);
|
||||
io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y);
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
case WM_MOUSELEAVE:
|
||||
case WM_NCMOUSELEAVE:
|
||||
@@ -640,21 +732,31 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
||||
bd->MouseTrackedArea = 0;
|
||||
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
||||
}
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
case WM_DESTROY:
|
||||
if (bd->MouseHwnd == hwnd && bd->MouseTrackedArea != 0)
|
||||
{
|
||||
TRACKMOUSEEVENT tme_cancel = { sizeof(tme_cancel), TME_CANCEL, hwnd, 0 };
|
||||
::TrackMouseEvent(&tme_cancel);
|
||||
bd->MouseHwnd = nullptr;
|
||||
bd->MouseTrackedArea = 0;
|
||||
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
||||
}
|
||||
return 0;
|
||||
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
|
||||
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
|
||||
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
|
||||
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK:
|
||||
{
|
||||
ImGuiMouseSource mouse_source = GetMouseSourceFromMessageExtraInfo();
|
||||
ImGuiMouseSource mouse_source = ImGui_ImplWin32_GetMouseSourceFromMessageExtraInfo();
|
||||
int button = 0;
|
||||
if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; }
|
||||
if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; }
|
||||
if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; }
|
||||
if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
|
||||
if (bd->MouseButtonsDown == 0 && ::GetCapture() == nullptr)
|
||||
::SetCapture(hwnd);
|
||||
::SetCapture(hwnd); // Allow us to read mouse coordinates when dragging mouse outside of our window bounds.
|
||||
bd->MouseButtonsDown |= 1 << button;
|
||||
io.AddMouseSourceEvent(mouse_source);
|
||||
io.AddMouseButtonEvent(button, true);
|
||||
@@ -665,7 +767,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
||||
case WM_MBUTTONUP:
|
||||
case WM_XBUTTONUP:
|
||||
{
|
||||
ImGuiMouseSource mouse_source = GetMouseSourceFromMessageExtraInfo();
|
||||
ImGuiMouseSource mouse_source = ImGui_ImplWin32_GetMouseSourceFromMessageExtraInfo();
|
||||
int button = 0;
|
||||
if (msg == WM_LBUTTONUP) { button = 0; }
|
||||
if (msg == WM_RBUTTONUP) { button = 1; }
|
||||
@@ -693,36 +795,37 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
||||
if (wParam < 256)
|
||||
{
|
||||
// Submit modifiers
|
||||
ImGui_ImplWin32_UpdateKeyModifiers();
|
||||
ImGui_ImplWin32_UpdateKeyModifiers(io);
|
||||
|
||||
// Obtain virtual key code
|
||||
// (keypad enter doesn't have its own... VK_RETURN with KF_EXTENDED flag means keypad enter, see IM_VK_KEYPAD_ENTER definition for details, it is mapped to ImGuiKey_KeyPadEnter.)
|
||||
int vk = (int)wParam;
|
||||
if ((wParam == VK_RETURN) && (HIWORD(lParam) & KF_EXTENDED))
|
||||
vk = IM_VK_KEYPAD_ENTER;
|
||||
// Obtain virtual key code and convert to ImGuiKey
|
||||
const ImGuiKey key = ImGui_ImplWin32_KeyEventToImGuiKey(wParam, lParam);
|
||||
const int vk = (int)wParam;
|
||||
const int scancode = (int)LOBYTE(HIWORD(lParam));
|
||||
|
||||
// Special behavior for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows doesn't emit the key down event.
|
||||
if (key == ImGuiKey_PrintScreen && !is_key_down)
|
||||
ImGui_ImplWin32_AddKeyEvent(io, key, true, vk, scancode);
|
||||
|
||||
// Submit key event
|
||||
const ImGuiKey key = ImGui_ImplWin32_VirtualKeyToImGuiKey(vk);
|
||||
const int scancode = (int)LOBYTE(HIWORD(lParam));
|
||||
if (key != ImGuiKey_None)
|
||||
ImGui_ImplWin32_AddKeyEvent(key, is_key_down, vk, scancode);
|
||||
ImGui_ImplWin32_AddKeyEvent(io, key, is_key_down, vk, scancode);
|
||||
|
||||
// Submit individual left/right modifier events
|
||||
if (vk == VK_SHIFT)
|
||||
{
|
||||
// Important: Shift keys tend to get stuck when pressed together, missing key-up events are corrected in ImGui_ImplWin32_ProcessKeyEventsWorkarounds()
|
||||
if (IsVkDown(VK_LSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftShift, is_key_down, VK_LSHIFT, scancode); }
|
||||
if (IsVkDown(VK_RSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightShift, is_key_down, VK_RSHIFT, scancode); }
|
||||
if (IsVkDown(VK_LSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_LeftShift, is_key_down, VK_LSHIFT, scancode); }
|
||||
if (IsVkDown(VK_RSHIFT) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_RightShift, is_key_down, VK_RSHIFT, scancode); }
|
||||
}
|
||||
else if (vk == VK_CONTROL)
|
||||
{
|
||||
if (IsVkDown(VK_LCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftCtrl, is_key_down, VK_LCONTROL, scancode); }
|
||||
if (IsVkDown(VK_RCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightCtrl, is_key_down, VK_RCONTROL, scancode); }
|
||||
if (IsVkDown(VK_LCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_LeftCtrl, is_key_down, VK_LCONTROL, scancode); }
|
||||
if (IsVkDown(VK_RCONTROL) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_RightCtrl, is_key_down, VK_RCONTROL, scancode); }
|
||||
}
|
||||
else if (vk == VK_MENU)
|
||||
{
|
||||
if (IsVkDown(VK_LMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_LeftAlt, is_key_down, VK_LMENU, scancode); }
|
||||
if (IsVkDown(VK_RMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(ImGuiKey_RightAlt, is_key_down, VK_RMENU, scancode); }
|
||||
if (IsVkDown(VK_LMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_LeftAlt, is_key_down, VK_LMENU, scancode); }
|
||||
if (IsVkDown(VK_RMENU) == is_key_down) { ImGui_ImplWin32_AddKeyEvent(io, ImGuiKey_RightAlt, is_key_down, VK_RMENU, scancode); }
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -731,6 +834,9 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
||||
case WM_KILLFOCUS:
|
||||
io.AddFocusEvent(msg == WM_SETFOCUS);
|
||||
return 0;
|
||||
case WM_INPUTLANGCHANGE:
|
||||
ImGui_ImplWin32_UpdateKeyboardCodePage(io);
|
||||
return 0;
|
||||
case WM_CHAR:
|
||||
if (::IsWindowUnicode(hwnd))
|
||||
{
|
||||
@@ -741,13 +847,13 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
||||
else
|
||||
{
|
||||
wchar_t wch = 0;
|
||||
::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (char*)&wParam, 1, &wch, 1);
|
||||
::MultiByteToWideChar(bd->KeyboardCodePage, MB_PRECOMPOSED, (char*)&wParam, 1, &wch, 1);
|
||||
io.AddInputCharacter(wch);
|
||||
}
|
||||
return 0;
|
||||
case WM_SETCURSOR:
|
||||
// This is required to restore cursor when transitioning from e.g resize borders to client area.
|
||||
if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor())
|
||||
if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor(io, bd->LastMouseCursor))
|
||||
return 1;
|
||||
return 0;
|
||||
case WM_DEVICECHANGE:
|
||||
@@ -886,7 +992,47 @@ float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd)
|
||||
return ImGui_ImplWin32_GetDpiScaleForMonitor(monitor);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------
|
||||
// Transparency related helpers (optional)
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma comment(lib, "dwmapi") // Link with dwmapi.lib. MinGW will require linking with '-ldwmapi'
|
||||
#endif
|
||||
|
||||
// [experimental]
|
||||
// Borrowed from GLFW's function updateFramebufferTransparency() in src/win32_window.c
|
||||
// (the Dwm* functions are Vista era functions but we are borrowing logic from GLFW)
|
||||
void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd)
|
||||
{
|
||||
if (!_IsWindowsVistaOrGreater())
|
||||
return;
|
||||
|
||||
BOOL composition;
|
||||
if (FAILED(::DwmIsCompositionEnabled(&composition)) || !composition)
|
||||
return;
|
||||
|
||||
BOOL opaque;
|
||||
DWORD color;
|
||||
if (_IsWindows8OrGreater() || (SUCCEEDED(::DwmGetColorizationColor(&color, &opaque)) && !opaque))
|
||||
{
|
||||
HRGN region = ::CreateRectRgn(0, 0, -1, -1);
|
||||
DWM_BLURBEHIND bb = {};
|
||||
bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
|
||||
bb.hRgnBlur = region;
|
||||
bb.fEnable = TRUE;
|
||||
::DwmEnableBlurBehindWindow((HWND)hwnd, &bb);
|
||||
::DeleteObject(region);
|
||||
}
|
||||
else
|
||||
{
|
||||
DWM_BLURBEHIND bb = {};
|
||||
bb.dwFlags = DWM_BB_ENABLE;
|
||||
::DwmEnableBlurBehindWindow((HWND)hwnd, &bb);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
||||
@@ -896,11 +1042,12 @@ float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd)
|
||||
struct ImGui_ImplWin32_ViewportData
|
||||
{
|
||||
HWND Hwnd;
|
||||
HWND HwndParent;
|
||||
bool HwndOwned;
|
||||
DWORD DwStyle;
|
||||
DWORD DwExStyle;
|
||||
|
||||
ImGui_ImplWin32_ViewportData() { Hwnd = nullptr; HwndOwned = false; DwStyle = DwExStyle = 0; }
|
||||
ImGui_ImplWin32_ViewportData() { Hwnd = HwndParent = nullptr; HwndOwned = false; DwStyle = DwExStyle = 0; }
|
||||
~ImGui_ImplWin32_ViewportData() { IM_ASSERT(Hwnd == nullptr); }
|
||||
};
|
||||
|
||||
@@ -920,6 +1067,14 @@ static void ImGui_ImplWin32_GetWin32StyleFromViewportFlags(ImGuiViewportFlags fl
|
||||
*out_ex_style |= WS_EX_TOPMOST;
|
||||
}
|
||||
|
||||
static HWND ImGui_ImplWin32_GetHwndFromViewportID(ImGuiID viewport_id)
|
||||
{
|
||||
if (viewport_id != 0)
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByID(viewport_id))
|
||||
return (HWND)viewport->PlatformHandle;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = IM_NEW(ImGui_ImplWin32_ViewportData)();
|
||||
@@ -927,21 +1082,21 @@ static void ImGui_ImplWin32_CreateWindow(ImGuiViewport* viewport)
|
||||
|
||||
// Select style and parent window
|
||||
ImGui_ImplWin32_GetWin32StyleFromViewportFlags(viewport->Flags, &vd->DwStyle, &vd->DwExStyle);
|
||||
HWND parent_window = nullptr;
|
||||
if (viewport->ParentViewportId != 0)
|
||||
if (ImGuiViewport* parent_viewport = ImGui::FindViewportByID(viewport->ParentViewportId))
|
||||
parent_window = (HWND)parent_viewport->PlatformHandle;
|
||||
vd->HwndParent = ImGui_ImplWin32_GetHwndFromViewportID(viewport->ParentViewportId);
|
||||
|
||||
// Create window
|
||||
RECT rect = { (LONG)viewport->Pos.x, (LONG)viewport->Pos.y, (LONG)(viewport->Pos.x + viewport->Size.x), (LONG)(viewport->Pos.y + viewport->Size.y) };
|
||||
::AdjustWindowRectEx(&rect, vd->DwStyle, FALSE, vd->DwExStyle);
|
||||
vd->Hwnd = ::CreateWindowEx(
|
||||
vd->DwExStyle, _T("ImGui Platform"), _T("Untitled"), vd->DwStyle, // Style, class name, window name
|
||||
vd->Hwnd = ::CreateWindowExW(
|
||||
vd->DwExStyle, L"ImGui Platform", L"Untitled", vd->DwStyle, // Style, class name, window name
|
||||
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, // Window area
|
||||
parent_window, nullptr, ::GetModuleHandle(nullptr), nullptr); // Parent window, Menu, Instance, Param
|
||||
vd->HwndParent, nullptr, ::GetModuleHandle(nullptr), nullptr); // Owner window, Menu, Instance, Param
|
||||
vd->HwndOwned = true;
|
||||
viewport->PlatformRequestResize = false;
|
||||
viewport->PlatformHandle = viewport->PlatformHandleRaw = vd->Hwnd;
|
||||
|
||||
// Secondary viewports store their imgui context
|
||||
::SetPropA(vd->Hwnd, "IMGUI_CONTEXT", ImGui::GetCurrentContext());
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_DestroyWindow(ImGuiViewport* viewport)
|
||||
@@ -967,18 +1122,44 @@ static void ImGui_ImplWin32_ShowWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
|
||||
// ShowParent() also brings parent to front, which is not always desirable,
|
||||
// so we temporarily disable parenting. (#7354)
|
||||
if (vd->HwndParent != NULL)
|
||||
::SetWindowLongPtr(vd->Hwnd, GWLP_HWNDPARENT, (LONG_PTR)nullptr);
|
||||
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing)
|
||||
::ShowWindow(vd->Hwnd, SW_SHOWNA);
|
||||
else
|
||||
::ShowWindow(vd->Hwnd, SW_SHOW);
|
||||
|
||||
// Restore
|
||||
if (vd->HwndParent != NULL)
|
||||
::SetWindowLongPtr(vd->Hwnd, GWLP_HWNDPARENT, (LONG_PTR)vd->HwndParent);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_UpdateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
// (Optional) Update Win32 style if it changed _after_ creation.
|
||||
// Generally they won't change unless configuration flags are changed, but advanced uses (such as manually rewriting viewport flags) make this useful.
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
|
||||
// Update Win32 parent if it changed _after_ creation
|
||||
// Unlike style settings derived from configuration flags, this is more likely to change for advanced apps that are manipulating ParentViewportID manually.
|
||||
HWND new_parent = ImGui_ImplWin32_GetHwndFromViewportID(viewport->ParentViewportId);
|
||||
if (new_parent != vd->HwndParent)
|
||||
{
|
||||
// Win32 windows can either have a "Parent" (for WS_CHILD window) or an "Owner" (which among other thing keeps window above its owner).
|
||||
// Our Dear Imgui-side concept of parenting only mostly care about what Win32 call "Owner".
|
||||
// The parent parameter of CreateWindowEx() sets up Parent OR Owner depending on WS_CHILD flag. In our case an Owner as we never use WS_CHILD.
|
||||
// Calling ::SetParent() here would be incorrect: it will create a full child relation, alter coordinate system and clipping.
|
||||
// Calling ::SetWindowLongPtr() with GWLP_HWNDPARENT seems correct although poorly documented.
|
||||
// https://devblogs.microsoft.com/oldnewthing/20100315-00/?p=14613
|
||||
vd->HwndParent = new_parent;
|
||||
::SetWindowLongPtr(vd->Hwnd, GWLP_HWNDPARENT, (LONG_PTR)vd->HwndParent);
|
||||
}
|
||||
|
||||
// (Optional) Update Win32 style if it changed _after_ creation.
|
||||
// Generally they won't change unless configuration flags are changed, but advanced uses (such as manually rewriting viewport flags) make this useful.
|
||||
DWORD new_style;
|
||||
DWORD new_ex_style;
|
||||
ImGui_ImplWin32_GetWin32StyleFromViewportFlags(viewport->Flags, &new_style, &new_ex_style);
|
||||
@@ -1013,11 +1194,20 @@ static ImVec2 ImGui_ImplWin32_GetWindowPos(ImGuiViewport* viewport)
|
||||
return ImVec2((float)pos.x, (float)pos.y);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_UpdateWin32StyleFromWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
vd->DwStyle = ::GetWindowLongW(vd->Hwnd, GWL_STYLE);
|
||||
vd->DwExStyle = ::GetWindowLongW(vd->Hwnd, GWL_EXSTYLE);
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
|
||||
{
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
RECT rect = { (LONG)pos.x, (LONG)pos.y, (LONG)pos.x, (LONG)pos.y };
|
||||
if (viewport->Flags & ImGuiViewportFlags_OwnedByApp)
|
||||
ImGui_ImplWin32_UpdateWin32StyleFromWindow(viewport); // Not our window, poll style before using
|
||||
::AdjustWindowRectEx(&rect, vd->DwStyle, FALSE, vd->DwExStyle);
|
||||
::SetWindowPos(vd->Hwnd, nullptr, rect.left, rect.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
}
|
||||
@@ -1036,6 +1226,8 @@ static void ImGui_ImplWin32_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
||||
IM_ASSERT(vd->Hwnd != 0);
|
||||
RECT rect = { 0, 0, (LONG)size.x, (LONG)size.y };
|
||||
if (viewport->Flags & ImGuiViewportFlags_OwnedByApp)
|
||||
ImGui_ImplWin32_UpdateWin32StyleFromWindow(viewport); // Not our window, poll style before using
|
||||
::AdjustWindowRectEx(&rect, vd->DwStyle, FALSE, vd->DwExStyle); // Client to Screen
|
||||
::SetWindowPos(vd->Hwnd, nullptr, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
|
||||
}
|
||||
@@ -1082,14 +1274,14 @@ static void ImGui_ImplWin32_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
|
||||
IM_ASSERT(alpha >= 0.0f && alpha <= 1.0f);
|
||||
if (alpha < 1.0f)
|
||||
{
|
||||
DWORD style = ::GetWindowLongW(vd->Hwnd, GWL_EXSTYLE) | WS_EX_LAYERED;
|
||||
::SetWindowLongW(vd->Hwnd, GWL_EXSTYLE, style);
|
||||
DWORD ex_style = ::GetWindowLongW(vd->Hwnd, GWL_EXSTYLE) | WS_EX_LAYERED;
|
||||
::SetWindowLongW(vd->Hwnd, GWL_EXSTYLE, ex_style);
|
||||
::SetLayeredWindowAttributes(vd->Hwnd, 0, (BYTE)(255 * alpha), LWA_ALPHA);
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD style = ::GetWindowLongW(vd->Hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED;
|
||||
::SetWindowLongW(vd->Hwnd, GWL_EXSTYLE, style);
|
||||
DWORD ex_style = ::GetWindowLongW(vd->Hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED;
|
||||
::SetWindowLongW(vd->Hwnd, GWL_EXSTYLE, ex_style);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1116,18 +1308,27 @@ static void ImGui_ImplWin32_OnChangedViewport(ImGuiViewport* viewport)
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace ImGui { extern ImGuiIO& GetIOEx(ImGuiContext*); extern ImGuiPlatformIO& GetPlatformIOEx(ImGuiContext*); }
|
||||
|
||||
static LRESULT CALLBACK ImGui_ImplWin32_WndProcHandler_PlatformWindow(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
|
||||
return true;
|
||||
// Allow secondary viewport WndProc to be called regardless of current context
|
||||
ImGuiContext* ctx = (ImGuiContext*)::GetPropA(hWnd, "IMGUI_CONTEXT");
|
||||
if (ctx == NULL)
|
||||
return DefWindowProc(hWnd, msg, wParam, lParam); // unlike ImGui_ImplWin32_WndProcHandler() we are called directly by Windows, we can't just return 0.
|
||||
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)hWnd))
|
||||
ImGuiIO& io = ImGui::GetIOEx(ctx);
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIOEx(ctx);
|
||||
LRESULT result = 0;
|
||||
if (ImGui_ImplWin32_WndProcHandlerEx(hWnd, msg, wParam, lParam, io))
|
||||
result = true;
|
||||
else if (ImGuiViewport* viewport = ImGui_ImplWin32_FindViewportByPlatformHandle(platform_io, hWnd))
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case WM_CLOSE:
|
||||
viewport->PlatformRequestClose = true;
|
||||
return 0;
|
||||
break;
|
||||
case WM_MOVE:
|
||||
viewport->PlatformRequestMove = true;
|
||||
break;
|
||||
@@ -1136,7 +1337,7 @@ static LRESULT CALLBACK ImGui_ImplWin32_WndProcHandler_PlatformWindow(HWND hWnd,
|
||||
break;
|
||||
case WM_MOUSEACTIVATE:
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnClick)
|
||||
return MA_NOACTIVATE;
|
||||
result = MA_NOACTIVATE;
|
||||
break;
|
||||
case WM_NCHITTEST:
|
||||
// Let mouse pass-through the window. This will allow the backend to call io.AddMouseViewportEvent() correctly. (which is optional).
|
||||
@@ -1144,19 +1345,20 @@ static LRESULT CALLBACK ImGui_ImplWin32_WndProcHandler_PlatformWindow(HWND hWnd,
|
||||
// If you cannot easily access those viewport flags from your windowing/event code: you may manually synchronize its state e.g. in
|
||||
// your main loop after calling UpdatePlatformWindows(). Iterate all viewports/platform windows and pass the flag to your windowing system.
|
||||
if (viewport->Flags & ImGuiViewportFlags_NoInputs)
|
||||
return HTTRANSPARENT;
|
||||
result = HTTRANSPARENT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
if (result == 0)
|
||||
result = DefWindowProc(hWnd, msg, wParam, lParam);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_InitPlatformInterface()
|
||||
static void ImGui_ImplWin32_InitMultiViewportSupport(bool platform_has_own_dc)
|
||||
{
|
||||
WNDCLASSEX wcex;
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW;
|
||||
WNDCLASSEXW wcex;
|
||||
wcex.cbSize = sizeof(WNDCLASSEXW);
|
||||
wcex.style = CS_HREDRAW | CS_VREDRAW | (platform_has_own_dc ? CS_OWNDC : 0);
|
||||
wcex.lpfnWndProc = ImGui_ImplWin32_WndProcHandler_PlatformWindow;
|
||||
wcex.cbClsExtra = 0;
|
||||
wcex.cbWndExtra = 0;
|
||||
@@ -1165,9 +1367,9 @@ static void ImGui_ImplWin32_InitPlatformInterface()
|
||||
wcex.hCursor = nullptr;
|
||||
wcex.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
|
||||
wcex.lpszMenuName = nullptr;
|
||||
wcex.lpszClassName = _T("ImGui Platform");
|
||||
wcex.lpszClassName = L"ImGui Platform";
|
||||
wcex.hIconSm = nullptr;
|
||||
::RegisterClassEx(&wcex);
|
||||
::RegisterClassExW(&wcex);
|
||||
|
||||
ImGui_ImplWin32_UpdateMonitors();
|
||||
|
||||
@@ -1197,53 +1399,21 @@ static void ImGui_ImplWin32_InitPlatformInterface()
|
||||
vd->Hwnd = bd->hWnd;
|
||||
vd->HwndOwned = false;
|
||||
main_viewport->PlatformUserData = vd;
|
||||
main_viewport->PlatformHandle = (void*)bd->hWnd;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_ShutdownPlatformInterface()
|
||||
static void ImGui_ImplWin32_ShutdownMultiViewportSupport()
|
||||
{
|
||||
::UnregisterClass(_T("ImGui Platform"), ::GetModuleHandle(nullptr));
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------
|
||||
// Transparency related helpers (optional)
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma comment(lib, "dwmapi") // Link with dwmapi.lib. MinGW will require linking with '-ldwmapi'
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
// [experimental]
|
||||
// Borrowed from GLFW's function updateFramebufferTransparency() in src/win32_window.c
|
||||
// (the Dwm* functions are Vista era functions but we are borrowing logic from GLFW)
|
||||
void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd)
|
||||
{
|
||||
if (!_IsWindowsVistaOrGreater())
|
||||
return;
|
||||
|
||||
BOOL composition;
|
||||
if (FAILED(::DwmIsCompositionEnabled(&composition)) || !composition)
|
||||
return;
|
||||
|
||||
BOOL opaque;
|
||||
DWORD color;
|
||||
if (_IsWindows8OrGreater() || (SUCCEEDED(::DwmGetColorizationColor(&color, &opaque)) && !opaque))
|
||||
{
|
||||
HRGN region = ::CreateRectRgn(0, 0, -1, -1);
|
||||
DWM_BLURBEHIND bb = {};
|
||||
bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
|
||||
bb.hRgnBlur = region;
|
||||
bb.fEnable = TRUE;
|
||||
::DwmEnableBlurBehindWindow((HWND)hwnd, &bb);
|
||||
::DeleteObject(region);
|
||||
}
|
||||
else
|
||||
{
|
||||
DWM_BLURBEHIND bb = {};
|
||||
bb.dwFlags = DWM_BB_ENABLE;
|
||||
::DwmEnableBlurBehindWindow((HWND)hwnd, &bb);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
+12
-4
@@ -4,20 +4,26 @@
|
||||
// Implemented features:
|
||||
// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen/Pen.
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values will also be supported unless IMGUI_DISABLE_OBSOLETE_KEYIO is set]
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd);
|
||||
IMGUI_IMPL_API bool ImGui_ImplWin32_InitForOpenGL(void* hwnd);
|
||||
IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame();
|
||||
|
||||
@@ -44,3 +50,5 @@ IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); //
|
||||
// - Use to enable alpha compositing transparency with the desktop.
|
||||
// - Use together with e.g. clearing your framebuffer with zero-alpha.
|
||||
IMGUI_IMPL_API void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd); // HWND hwnd
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
Instructions to rebuild imgui_impl_sdlgpu3_shaders.h
|
||||
(You don't need to copy this folder if you are using the backend as-is)
|
||||
|
||||
1) Compile the raw shader files to SPIRV:
|
||||
|
||||
glslc -o vertex.spv -c shader.vert
|
||||
glslc -o fragment.spv -c shader.frag
|
||||
|
||||
|
||||
2) Build SDL_shadercross (https://github.com/libsdl-org/SDL_shadercross)
|
||||
|
||||
|
||||
3-A) Compiling for the Vulkan Driver:
|
||||
|
||||
Nothing to do, you just need the previous vertex.spv/fragment.spv, proceed to step 4
|
||||
|
||||
|
||||
3-B) Compiling for the DirectX 12 Driver:
|
||||
|
||||
./shadercross vertex.spv -s SPIRV -d DXBC -t vertex -e main -o vertex.dxbc
|
||||
./shadercross fragment.spv -s SPIRV -d DXBC -t fragment -e main -o fragment.dxbc
|
||||
|
||||
Proceed to step 4
|
||||
|
||||
|
||||
3-C) Compiling for Metal (On windows you'll need the Metal Developer Tools for Windows, on linux you might use wine, but I never tested it):
|
||||
|
||||
./shadercross vertex.spv -s SPIRV -d MSL -t vertex -e main -o vertex.metal
|
||||
./shadercross fragment.spv -s SPIRV -d MSL -t fragment -e main -o fragment.metal
|
||||
|
||||
xcrun -sdk macosx metal -o vertex.ir -c vertex.metal
|
||||
xcrun -sdk macosx metal -o fragment.ir -c fragment.metal
|
||||
xcrun -sdk macosx metallib -o vertex.metallib -c vertex.ir
|
||||
xcrun -sdk macosx metallib -o fragment.metallib -c fragment.ir
|
||||
|
||||
Proceed to step 4
|
||||
|
||||
|
||||
4) Use a tool like https://notisrac.github.io/FileToCArray/ or misc/fonts/binary_to_compressed_c.cpp in imgui repository to convert the file to a uint8_t array.
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
#version 450 core
|
||||
layout(location = 0) out vec4 fColor;
|
||||
|
||||
layout(set=2, binding=0) uniform sampler2D sTexture;
|
||||
|
||||
layout(location = 0) in struct
|
||||
{
|
||||
vec4 Color;
|
||||
vec2 UV;
|
||||
} In;
|
||||
|
||||
void main()
|
||||
{
|
||||
fColor = In.Color * texture(sTexture, In.UV.st);
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
#version 450 core
|
||||
layout(location = 0) in vec2 aPos;
|
||||
layout(location = 1) in vec2 aUV;
|
||||
layout(location = 2) in vec4 aColor;
|
||||
|
||||
layout(set=1,binding=0) uniform UBO
|
||||
{
|
||||
vec2 uScale;
|
||||
vec2 uTranslate;
|
||||
} ubo;
|
||||
|
||||
layout(location = 0) out struct
|
||||
{
|
||||
vec4 Color;
|
||||
vec2 UV;
|
||||
} Out;
|
||||
|
||||
void main()
|
||||
{
|
||||
Out.Color = aColor;
|
||||
Out.UV = aUV;
|
||||
gl_Position = vec4(aPos * ubo.uScale + ubo.uTranslate, 0, 1);
|
||||
gl_Position.y *= -1.0f;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
|
||||
Script to rebuild shaders stored inside imgui_impl_vulkan.h
|
||||
(You don't need to copy this folder if you are using the backend as-is)
|
||||
|
||||
Reference in New Issue
Block a user