mirror of https://github.com/axmolengine/axmol.git
Fix #507
This commit is contained in:
parent
629625a976
commit
24f76a53b3
|
@ -1,3 +1,9 @@
|
||||||
|
/*
|
||||||
|
* The imgui adxe backend
|
||||||
|
* refer to
|
||||||
|
* a. https://github.com/ocornut/imgui/blob/835a5344b01e79aca479e95fa9d36fb5fdef3d14/backends/imgui_impl_glfw.cpp
|
||||||
|
* b. https://github.com/Xrysnow/cocos2d-x-imgui/blob/master/imgui_impl_cocos2dx.cpp
|
||||||
|
*/
|
||||||
#include "imgui_impl_cocos2dx.h"
|
#include "imgui_impl_cocos2dx.h"
|
||||||
#include "cocos2d.h"
|
#include "cocos2d.h"
|
||||||
#include "renderer/backend/Backend.h"
|
#include "renderer/backend/Backend.h"
|
||||||
|
@ -5,27 +11,32 @@
|
||||||
|
|
||||||
#ifdef CC_PLATFORM_PC
|
#ifdef CC_PLATFORM_PC
|
||||||
// GLFW
|
// GLFW
|
||||||
|
#include "glfw3.h"
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "glfw3.h"
|
|
||||||
#undef APIENTRY
|
#undef APIENTRY
|
||||||
#ifndef GLFW_EXPOSE_NATIVE_WIN32
|
#ifndef GLFW_EXPOSE_NATIVE_WIN32
|
||||||
#define GLFW_EXPOSE_NATIVE_WIN32
|
#define GLFW_EXPOSE_NATIVE_WIN32
|
||||||
#endif
|
#endif
|
||||||
#include "glfw3native.h"
|
#include "glfw3native.h"
|
||||||
#else
|
|
||||||
#include <glfw3.h>
|
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
#define GLFW_HAS_WINDOW_TOPMOST (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ GLFW_FLOATING
|
||||||
static_assert(
|
#define GLFW_HAS_WINDOW_HOVERED (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ GLFW_HOVERED
|
||||||
GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300,
|
#define GLFW_HAS_WINDOW_ALPHA (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwSetWindowOpacity
|
||||||
"glfw version should be 3.3+");
|
#define GLFW_HAS_PER_MONITOR_DPI (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwGetMonitorContentScale
|
||||||
|
#define GLFW_HAS_VULKAN (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ glfwCreateWindowSurface
|
||||||
// 3.3.1+ Fixed: Resizing window repositions it on MacOS #1553
|
#define GLFW_HAS_FOCUS_WINDOW (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ glfwFocusWindow
|
||||||
#define GLFW_HAS_OSX_WINDOW_POS_FIX (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 + GLFW_VERSION_REVISION * 10 >= 3310)
|
#define GLFW_HAS_FOCUS_ON_SHOW (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ GLFW_FOCUS_ON_SHOW
|
||||||
#ifdef GLFW_RESIZE_NESW_CURSOR
|
#define GLFW_HAS_MONITOR_WORK_AREA (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwGetMonitorWorkarea
|
||||||
#define GLFW_HAS_NEW_CURSORS (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3400)
|
#define GLFW_HAS_OSX_WINDOW_POS_FIX (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 + GLFW_VERSION_REVISION * 10 >= 3310) // 3.3.1+ Fixed: Resizing window repositions it on MacOS #1553
|
||||||
|
#ifdef GLFW_RESIZE_NESW_CURSOR // Let's be nice to people who pulled GLFW between 2019-04-16 (3.4 define) and 2019-11-29 (cursors defines) // FIXME: Remove when GLFW 3.4 is released?
|
||||||
|
#define GLFW_HAS_NEW_CURSORS (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3400) // 3.4+ GLFW_RESIZE_ALL_CURSOR, GLFW_RESIZE_NESW_CURSOR, GLFW_RESIZE_NWSE_CURSOR, GLFW_NOT_ALLOWED_CURSOR
|
||||||
#else
|
#else
|
||||||
#define GLFW_HAS_NEW_CURSORS (0)
|
#define GLFW_HAS_NEW_CURSORS (0)
|
||||||
|
#endif
|
||||||
|
#ifdef GLFW_MOUSE_PASSTHROUGH // Let's be nice to people who pulled GLFW between 2019-04-16 (3.4 define) and 2020-07-17 (passthrough)
|
||||||
|
#define GLFW_HAS_MOUSE_PASSTHROUGH (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3400) // 3.4+ GLFW_MOUSE_PASSTHROUGH
|
||||||
|
#else
|
||||||
|
#define GLFW_HAS_MOUSE_PASSTHROUGH (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // CC_PLATFORM_PC
|
#endif // CC_PLATFORM_PC
|
||||||
|
@ -264,6 +275,8 @@ void ImGui_ImplCocos2dx_RenderDrawData(ImDrawData* draw_data)
|
||||||
*desc.programState->getVertexLayout() = pinfo->layout;
|
*desc.programState->getVertexLayout() = pinfo->layout;
|
||||||
desc.programState->setUniform(pinfo->projection, &g_Projection, sizeof(Mat4));
|
desc.programState->setUniform(pinfo->projection, &g_Projection, sizeof(Mat4));
|
||||||
desc.programState->setTexture(pinfo->texture, 0, tex->getBackendTexture());
|
desc.programState->setTexture(pinfo->texture, 0, tex->getBackendTexture());
|
||||||
|
// In order to composite our output buffer we need to preserve alpha
|
||||||
|
desc.blendDescriptor.sourceAlphaBlendFactor = BlendFactor::ONE;
|
||||||
// set vertex/index buffer
|
// set vertex/index buffer
|
||||||
cmd->setIndexBuffer(ibuffer, g_IndexFormat);
|
cmd->setIndexBuffer(ibuffer, g_IndexFormat);
|
||||||
cmd->setVertexBuffer(vbuffer);
|
cmd->setVertexBuffer(vbuffer);
|
||||||
|
@ -785,99 +798,108 @@ void ImGui_ImplCocos2dx_Shutdown()
|
||||||
static void ImGui_ImplCocos2dx_UpdateMousePosAndButtons()
|
static void ImGui_ImplCocos2dx_UpdateMousePosAndButtons()
|
||||||
{
|
{
|
||||||
#ifdef CC_PLATFORM_PC
|
#ifdef CC_PLATFORM_PC
|
||||||
const auto g_Window = ImGui_ImplCocos2dx_GetWindow();
|
const auto g_Window = ImGui_ImplCocos2dx_GetWindow();
|
||||||
// Update buttons
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
|
||||||
|
const ImVec2 mouse_pos_prev = io.MousePos;
|
||||||
|
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
||||||
|
io.MouseHoveredViewport = 0;
|
||||||
|
|
||||||
|
// Update mouse buttons
|
||||||
|
// (if a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame)
|
||||||
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
|
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
|
||||||
{
|
{
|
||||||
// If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
|
|
||||||
io.MouseDown[i] = g_MouseJustPressed[i] || glfwGetMouseButton(g_Window, i) != 0;
|
io.MouseDown[i] = g_MouseJustPressed[i] || glfwGetMouseButton(g_Window, i) != 0;
|
||||||
g_MouseJustPressed[i] = false;
|
g_MouseJustPressed[i] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int n = 0; n < platform_io.Viewports.Size; n++)
|
||||||
|
{
|
||||||
|
ImGuiViewport* viewport = platform_io.Viewports[n];
|
||||||
|
GLFWwindow* window = (GLFWwindow*)viewport->PlatformHandle;
|
||||||
|
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
const bool focused = true;
|
||||||
|
#else
|
||||||
|
const bool focused = glfwGetWindowAttrib(window, GLFW_FOCUSED) != 0;
|
||||||
|
#endif
|
||||||
|
GLFWwindow* mouse_window = window; // (bd->MouseWindow == window || focused) ? window : NULL;
|
||||||
|
|
||||||
|
// Update mouse buttons
|
||||||
|
if (focused)
|
||||||
|
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
|
||||||
|
io.MouseDown[i] |= glfwGetMouseButton(window, i) != 0;
|
||||||
|
|
||||||
|
// Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
||||||
|
// (When multi-viewports are enabled, all Dear ImGui positions are same as OS positions)
|
||||||
|
if (io.WantSetMousePos && focused)
|
||||||
|
glfwSetCursorPos(window, (double)(mouse_pos_prev.x - viewport->Pos.x), (double)(mouse_pos_prev.y - viewport->Pos.y));
|
||||||
|
|
||||||
|
// Set Dear ImGui mouse position from OS position
|
||||||
|
if (mouse_window != NULL)
|
||||||
|
{
|
||||||
|
double mouse_x, mouse_y;
|
||||||
|
glfwGetCursorPos(mouse_window, &mouse_x, &mouse_y);
|
||||||
|
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||||
|
{
|
||||||
|
// Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
|
||||||
|
int window_x, window_y;
|
||||||
|
glfwGetWindowPos(window, &window_x, &window_y);
|
||||||
|
io.MousePos = ImVec2((float)mouse_x + window_x, (float)mouse_y + window_y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Single viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
|
||||||
|
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// (Optional) When using multiple viewports: set io.MouseHoveredViewport to the viewport the OS mouse cursor is hovering.
|
||||||
|
// Important: this information is not easy to provide and many high-level windowing library won't be able to provide it correctly, because
|
||||||
|
// - This is _ignoring_ viewports with the ImGuiViewportFlags_NoInputs flag (pass-through windows).
|
||||||
|
// - This is _regardless_ of whether another viewport is focused or being dragged from.
|
||||||
|
// If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, imgui will ignore this field and infer the information by relying on the
|
||||||
|
// rectangles and last focused time of every viewports it knows about. It will be unaware of other windows that may be sitting between or over your windows.
|
||||||
|
// [GLFW] 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
|
||||||
|
glfwSetWindowAttrib(window, GLFW_MOUSE_PASSTHROUGH, window_no_input);
|
||||||
|
#endif
|
||||||
|
if (glfwGetWindowAttrib(window, GLFW_HOVERED) && !window_no_input)
|
||||||
|
io.MouseHoveredViewport = viewport->ID;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// Update buttons
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
|
||||||
|
{
|
||||||
|
// g_MouseJustPressed represents touch state on mobile platforms
|
||||||
|
io.MouseDown[i] = g_MouseJustPressed[i];
|
||||||
|
}
|
||||||
// Update mouse position
|
// Update mouse position
|
||||||
const ImVec2 mouse_pos_backup = io.MousePos;
|
const ImVec2 mouse_pos_backup = io.MousePos;
|
||||||
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
||||||
io.MouseHoveredViewport = 0;
|
if (io.WantSetMousePos)
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
{
|
||||||
for (int n = 0; n < platform_io.Viewports.Size; n++)
|
io.MousePos = mouse_pos_backup;
|
||||||
{
|
}
|
||||||
ImGuiViewport* viewport = platform_io.Viewports[n];
|
else
|
||||||
GLFWwindow* window = (GLFWwindow*)viewport->PlatformHandle;
|
{
|
||||||
IM_ASSERT(window != NULL);
|
if (g_CursorPos.x != -FLT_MAX && g_CursorPos.y != -FLT_MAX)
|
||||||
#ifdef __EMSCRIPTEN__
|
{
|
||||||
const bool focused = true;
|
// convert g_CursorPos
|
||||||
IM_ASSERT(platform_io.Viewports.Size == 1);
|
const auto glv = cocos2d::Director::getInstance()->getOpenGLView();
|
||||||
#else
|
const auto rect = glv->getViewPortRect();
|
||||||
const bool focused = glfwGetWindowAttrib(window, GLFW_FOCUSED) != 0;
|
io.MousePos.x = g_CursorPos.x * glv->getScaleX() + rect.origin.x;
|
||||||
|
io.MousePos.y = g_CursorPos.y * glv->getScaleY() + rect.origin.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
if (focused)
|
|
||||||
{
|
|
||||||
if (io.WantSetMousePos)
|
|
||||||
{
|
|
||||||
glfwSetCursorPos(window, (double)mouse_pos_backup.x, (double)mouse_pos_backup.y);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
double mouse_x, mouse_y;
|
|
||||||
glfwGetCursorPos(window, &mouse_x, &mouse_y);
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
||||||
{
|
|
||||||
// Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
|
|
||||||
int window_x, window_y;
|
|
||||||
glfwGetWindowPos(window, &window_x, &window_y);
|
|
||||||
io.MousePos = ImVec2((float)mouse_x + window_x, (float)mouse_y + window_y);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Single viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
|
|
||||||
io.MousePos = ImVec2((float)mouse_x, (float)mouse_y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
|
|
||||||
io.MouseDown[i] |= glfwGetMouseButton(window, i) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// (Optional) When using multiple viewports: set io.MouseHoveredViewport to the viewport the OS mouse cursor is hovering.
|
|
||||||
// Important: this information is not easy to provide and many high-level windowing library won't be able to provide it correctly, because
|
|
||||||
// - This is _ignoring_ viewports with the ImGuiViewportFlags_NoInputs flag (pass-through windows).
|
|
||||||
// - This is _regardless_ of whether another viewport is focused or being dragged from.
|
|
||||||
// If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the back-end, imgui will ignore this field and infer the information by relying on the
|
|
||||||
// rectangles and last focused time of every viewports it knows about. It will be unaware of other windows that may be sitting between or over your windows.
|
|
||||||
// [GLFW] 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_GLFW_HOVERED && CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
|
|
||||||
if (glfwGetWindowAttrib(window, GLFW_HOVERED) && !(viewport->Flags & ImGuiViewportFlags_NoInputs))
|
|
||||||
io.MouseHoveredViewport = viewport->ID;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// Update buttons
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++)
|
|
||||||
{
|
|
||||||
// g_MouseJustPressed represents touch state on mobile platforms
|
|
||||||
io.MouseDown[i] = g_MouseJustPressed[i];
|
|
||||||
}
|
|
||||||
// Update mouse position
|
|
||||||
const ImVec2 mouse_pos_backup = io.MousePos;
|
|
||||||
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
|
||||||
if (io.WantSetMousePos)
|
|
||||||
{
|
|
||||||
io.MousePos = mouse_pos_backup;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (g_CursorPos.x != -FLT_MAX && g_CursorPos.y != -FLT_MAX)
|
|
||||||
{
|
|
||||||
// convert g_CursorPos
|
|
||||||
const auto glv = cocos2d::Director::getInstance()->getOpenGLView();
|
|
||||||
const auto rect = glv->getViewPortRect();
|
|
||||||
io.MousePos.x = g_CursorPos.x * glv->getScaleX() + rect.origin.x;
|
|
||||||
io.MousePos.y = g_CursorPos.y * glv->getScaleY() + rect.origin.y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // CC_PLATFORM_PC
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplCocos2dx_UpdateMouseCursor()
|
static void ImGui_ImplCocos2dx_UpdateMouseCursor()
|
||||||
|
@ -1173,7 +1195,7 @@ static void ImGui_ImplGlfw_DestroyWindow(ImGuiViewport* viewport)
|
||||||
AddRendererCommand([=]()
|
AddRendererCommand([=]()
|
||||||
{
|
{
|
||||||
#if GLFW_HAS_GLFW_HOVERED && CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
|
#if GLFW_HAS_GLFW_HOVERED && CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
|
||||||
HWND hwnd = PlatformHandleRaw;
|
HWND hwnd = (HWND)PlatformHandleRaw;
|
||||||
::RemovePropA(hwnd, "IMGUI_VIEWPORT");
|
::RemovePropA(hwnd, "IMGUI_VIEWPORT");
|
||||||
#endif
|
#endif
|
||||||
glfwDestroyWindow(window);
|
glfwDestroyWindow(window);
|
||||||
|
|
Loading…
Reference in New Issue