mirror of https://github.com/axmolengine/axmol.git
Enable ImGui for Android (#909)
* Add support for ImGui usage on Android
This commit is contained in:
parent
9c7a876970
commit
34094038d5
|
@ -18,7 +18,7 @@ option(AX_ENABLE_EXT_FAIRYGUI "Build extension FairyGUI" ON)
|
||||||
|
|
||||||
option(AX_ENABLE_EXT_LIVE2D "Build extension Live2D" OFF)
|
option(AX_ENABLE_EXT_LIVE2D "Build extension Live2D" OFF)
|
||||||
|
|
||||||
if(WINDOWS OR MACOSX OR LINUX)
|
if(WINDOWS OR MACOSX OR LINUX OR ANDROID)
|
||||||
option(AX_ENABLE_EXT_IMGUI "Build extension ImGui" ON)
|
option(AX_ENABLE_EXT_IMGUI "Build extension ImGui" ON)
|
||||||
else()
|
else()
|
||||||
set(AX_ENABLE_EXT_IMGUI OFF)
|
set(AX_ENABLE_EXT_IMGUI OFF)
|
||||||
|
|
|
@ -5,7 +5,6 @@ include_directories(imgui)
|
||||||
set(HEADER
|
set(HEADER
|
||||||
ImGuiPresenter.h
|
ImGuiPresenter.h
|
||||||
# CCImGuiColorTextEdit.h
|
# CCImGuiColorTextEdit.h
|
||||||
imgui_impl_ax.h
|
|
||||||
imgui/imconfig.h
|
imgui/imconfig.h
|
||||||
imgui/imgui.h
|
imgui/imgui.h
|
||||||
imgui/imgui_internal.h
|
imgui/imgui_internal.h
|
||||||
|
@ -21,7 +20,6 @@ set(HEADER
|
||||||
set(SOURCE
|
set(SOURCE
|
||||||
ImGuiPresenter.cpp
|
ImGuiPresenter.cpp
|
||||||
# CCImGuiColorTextEdit.cpp
|
# CCImGuiColorTextEdit.cpp
|
||||||
imgui_impl_ax.cpp
|
|
||||||
imgui/imgui.cpp
|
imgui/imgui.cpp
|
||||||
imgui/imgui_demo.cpp
|
imgui/imgui_demo.cpp
|
||||||
imgui/imgui_draw.cpp
|
imgui/imgui_draw.cpp
|
||||||
|
@ -33,6 +31,14 @@ set(SOURCE
|
||||||
#~ implot/implot_demo.cpp
|
#~ implot/implot_demo.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(ANDROID)
|
||||||
|
list(APPEND HEADER imgui_impl_ax_android.cpp)
|
||||||
|
list(APPEND SOURCE imgui_impl_ax_android.h)
|
||||||
|
else()
|
||||||
|
list(APPEND HEADER imgui_impl_ax.cpp)
|
||||||
|
list(APPEND SOURCE imgui_impl_ax.h)
|
||||||
|
endif()
|
||||||
|
|
||||||
#~ if(AX_ENABLE_EXT_LUA)
|
#~ if(AX_ENABLE_EXT_LUA)
|
||||||
#~ include_directories(
|
#~ include_directories(
|
||||||
#~ lua-bindings
|
#~ lua-bindings
|
||||||
|
@ -64,8 +70,8 @@ set(SOURCE
|
||||||
#~ )
|
#~ )
|
||||||
#~ endif()
|
#~ endif()
|
||||||
|
|
||||||
add_library(${target_name} STATIC
|
add_library(${target_name} STATIC
|
||||||
${HEADER}
|
${HEADER}
|
||||||
${SOURCE})
|
${SOURCE})
|
||||||
|
|
||||||
setup_ax_extension_config(${target_name})
|
setup_ax_extension_config(${target_name})
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
#include "ImGuiPresenter.h"
|
#include "ImGuiPresenter.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "imgui_impl_ax.h"
|
#if (AX_TARGET_PLATFORM == AX_PLATFORM_ANDROID)
|
||||||
|
#include "imgui_impl_ax_android.h"
|
||||||
|
#else
|
||||||
|
#include "imgui_impl_ax.h"
|
||||||
|
#endif
|
||||||
#include "imgui_internal.h"
|
#include "imgui_internal.h"
|
||||||
|
|
||||||
// TODO: mac metal
|
// TODO: mac metal
|
||||||
|
@ -197,8 +201,12 @@ void ImGuiPresenter::init()
|
||||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (AX_TARGET_PLATFORM == AX_PLATFORM_ANDROID)
|
||||||
|
ImGui_ImplAndroid_InitForAx(Director::getInstance()->getOpenGLView(), true);
|
||||||
|
#else
|
||||||
auto window = static_cast<GLViewImpl*>(Director::getInstance()->getOpenGLView())->getWindow();
|
auto window = static_cast<GLViewImpl*>(Director::getInstance()->getOpenGLView())->getWindow();
|
||||||
ImGui_ImplGlfw_InitForAx(window, true);
|
ImGui_ImplGlfw_InitForAx(window, true);
|
||||||
|
#endif
|
||||||
ImGui_ImplAx_Init();
|
ImGui_ImplAx_Init();
|
||||||
|
|
||||||
ImGui_ImplAx_SetCustomFontLoader(&ImGuiPresenter::loadCustomFonts, this);
|
ImGui_ImplAx_SetCustomFontLoader(&ImGuiPresenter::loadCustomFonts, this);
|
||||||
|
@ -218,7 +226,11 @@ void ImGuiPresenter::cleanup()
|
||||||
|
|
||||||
ImGui_ImplAx_SetCustomFontLoader(nullptr, nullptr);
|
ImGui_ImplAx_SetCustomFontLoader(nullptr, nullptr);
|
||||||
ImGui_ImplAx_Shutdown();
|
ImGui_ImplAx_Shutdown();
|
||||||
|
#if (AX_TARGET_PLATFORM == AX_PLATFORM_ANDROID)
|
||||||
|
ImGui_ImplAndroid_Shutdown();
|
||||||
|
#else
|
||||||
ImGui_ImplGlfw_Shutdown();
|
ImGui_ImplGlfw_Shutdown();
|
||||||
|
#endif
|
||||||
|
|
||||||
AX_SAFE_RELEASE_NULL(_fontsTexture);
|
AX_SAFE_RELEASE_NULL(_fontsTexture);
|
||||||
|
|
||||||
|
@ -265,9 +277,12 @@ void ImGuiPresenter::loadCustomFonts(void* ud)
|
||||||
|
|
||||||
float ImGuiPresenter::scaleAllByDPI(float userScale)
|
float ImGuiPresenter::scaleAllByDPI(float userScale)
|
||||||
{
|
{
|
||||||
// Gets scale
|
|
||||||
float xscale = 1.0f;
|
float xscale = 1.0f;
|
||||||
|
#if (AX_TARGET_PLATFORM != AX_PLATFORM_ANDROID)
|
||||||
|
// Gets scale
|
||||||
glfwGetMonitorContentScale(glfwGetPrimaryMonitor(), &xscale, nullptr);
|
glfwGetMonitorContentScale(glfwGetPrimaryMonitor(), &xscale, nullptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
auto zoomFactor = userScale * xscale;
|
auto zoomFactor = userScale * xscale;
|
||||||
|
|
||||||
auto imFonts = ImGui::GetIO().Fonts;
|
auto imFonts = ImGui::GetIO().Fonts;
|
||||||
|
@ -293,6 +308,11 @@ float ImGuiPresenter::scaleAllByDPI(float userScale)
|
||||||
return zoomFactor;
|
return zoomFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ImGuiPresenter::setViewResolution(float width, float height)
|
||||||
|
{
|
||||||
|
ImGui_ImplAx_SetViewResolution(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
void ImGuiPresenter::addFont(std::string_view fontFile, float fontSize, CHS_GLYPH_RANGE glyphRange)
|
void ImGuiPresenter::addFont(std::string_view fontFile, float fontSize, CHS_GLYPH_RANGE glyphRange)
|
||||||
{
|
{
|
||||||
if (FileUtils::getInstance()->isFileExistInternal(fontFile))
|
if (FileUtils::getInstance()->isFileExistInternal(fontFile))
|
||||||
|
@ -340,7 +360,11 @@ void ImGuiPresenter::beginFrame()
|
||||||
{
|
{
|
||||||
// create frame
|
// create frame
|
||||||
ImGui_ImplAx_NewFrame();
|
ImGui_ImplAx_NewFrame();
|
||||||
|
#if (AX_TARGET_PLATFORM == AX_PLATFORM_ANDROID)
|
||||||
|
ImGui_ImplAndroid_NewFrame();
|
||||||
|
#else
|
||||||
ImGui_ImplGlfw_NewFrame();
|
ImGui_ImplGlfw_NewFrame();
|
||||||
|
#endif
|
||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
|
|
||||||
// move to endFrame?
|
// move to endFrame?
|
||||||
|
|
|
@ -45,6 +45,8 @@ public:
|
||||||
float scaleAllByDPI(float userScale);
|
float scaleAllByDPI(float userScale);
|
||||||
float getContentZoomFactor() const { return _contentZoomFactor; }
|
float getContentZoomFactor() const { return _contentZoomFactor; }
|
||||||
|
|
||||||
|
void setViewResolution(float width, float height);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add ImGui font with contentZoomFactor
|
/// Add ImGui font with contentZoomFactor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1296,7 +1296,7 @@ void ImGui_ImplAx_Shutdown()
|
||||||
ImGui_ImplAx_DestroyDeviceObjects();
|
ImGui_ImplAx_DestroyDeviceObjects();
|
||||||
}
|
}
|
||||||
|
|
||||||
IMGUI_IMPL_API void ImGui_ImplAx_NewFrame() {
|
IMGUI_IMPL_API void ImGui_ImplAx_NewFrame() {
|
||||||
auto bd = ImGui_ImplGlfw_GetBackendData();
|
auto bd = ImGui_ImplGlfw_GetBackendData();
|
||||||
//bd->CallbackCommands.clear();
|
//bd->CallbackCommands.clear();
|
||||||
bd->CustomCommands.clear();
|
bd->CustomCommands.clear();
|
||||||
|
@ -1330,6 +1330,13 @@ IMGUI_IMPL_API void ImGui_ImplAx_SetDeviceObjectsDirty()
|
||||||
bd->FontDeviceObjectsDirty = true;
|
bd->FontDeviceObjectsDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAx_SetViewResolution(float width, float height)
|
||||||
|
{
|
||||||
|
// Resize (expand) window
|
||||||
|
auto* view = (GLViewImpl*)Director::getInstance()->getOpenGLView();
|
||||||
|
view->setWindowed(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
static void ImGui_ImplAx_CreateWindow(ImGuiViewport* viewport)
|
static void ImGui_ImplAx_CreateWindow(ImGuiViewport* viewport)
|
||||||
{
|
{
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||||
|
|
|
@ -23,3 +23,6 @@ IMGUI_IMPL_API void* ImGui_ImplAx_GetFontsTexture();
|
||||||
|
|
||||||
// Sets Device objects dirty
|
// Sets Device objects dirty
|
||||||
IMGUI_IMPL_API void ImGui_ImplAx_SetDeviceObjectsDirty();
|
IMGUI_IMPL_API void ImGui_ImplAx_SetDeviceObjectsDirty();
|
||||||
|
|
||||||
|
// Set the required view resolution for the UI
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAx_SetViewResolution(float width, float height);
|
||||||
|
|
|
@ -0,0 +1,715 @@
|
||||||
|
#include "imgui_impl_ax_android.h"
|
||||||
|
#include "cocos2d.h"
|
||||||
|
#include "renderer/backend/Backend.h"
|
||||||
|
#include <functional>
|
||||||
|
#include <android/native_window.h>
|
||||||
|
#include <android/input.h>
|
||||||
|
#include <android/keycodes.h>
|
||||||
|
#include <android/log.h>
|
||||||
|
|
||||||
|
USING_NS_AX;
|
||||||
|
using namespace backend;
|
||||||
|
|
||||||
|
// Clang warnings with -Weverything
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast
|
||||||
|
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||||
|
#if __has_warning("-Wzero-as-null-pointer-constant")
|
||||||
|
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// GLFW
|
||||||
|
|
||||||
|
// Android data
|
||||||
|
static char g_LogTag[] = "ImGuiAndroid";
|
||||||
|
|
||||||
|
// axmol spec data
|
||||||
|
constexpr IndexFormat IMGUI_INDEX_FORMAT = sizeof(ImDrawIdx) == 2 ? IndexFormat::U_SHORT : IndexFormat::U_INT;
|
||||||
|
|
||||||
|
struct ProgramInfoData
|
||||||
|
{
|
||||||
|
Program* program = nullptr;
|
||||||
|
// Uniforms location
|
||||||
|
UniformLocation texture{};
|
||||||
|
UniformLocation projection{};
|
||||||
|
// Vertex attributes location
|
||||||
|
int position = 0;
|
||||||
|
int uv = 0;
|
||||||
|
int color = 0;
|
||||||
|
VertexLayout layout{};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SavedRenderStateData
|
||||||
|
{
|
||||||
|
backend::CullMode cull{};
|
||||||
|
Viewport vp{};
|
||||||
|
ScissorRect scissorRect{};
|
||||||
|
bool scissorTest{};
|
||||||
|
bool depthTest{};
|
||||||
|
};
|
||||||
|
// end of axmol spec
|
||||||
|
|
||||||
|
|
||||||
|
struct ImGui_ImplAndroid_Data
|
||||||
|
{
|
||||||
|
GLView* Window;
|
||||||
|
double Time;
|
||||||
|
bool InstalledCallbacks;
|
||||||
|
|
||||||
|
// ImGui_ImplAndroid_Data() { memset(this, 0, sizeof(*this)); }
|
||||||
|
|
||||||
|
// axmol spec data
|
||||||
|
std::chrono::steady_clock::time_point LastFrameTime{};
|
||||||
|
|
||||||
|
ImGuiImplCocos2dxLoadFontFun LoadCustomFont = nullptr;
|
||||||
|
void* LoadCustomFontUserData = nullptr;
|
||||||
|
|
||||||
|
ProgramInfoData ProgramInfo{};
|
||||||
|
ProgramInfoData ProgramFontInfo{};
|
||||||
|
bool FontDeviceObjectsDirty = false;
|
||||||
|
Texture2D* FontTexture = nullptr;
|
||||||
|
Mat4 Projection;
|
||||||
|
ImVec2 LastValidMousePos;
|
||||||
|
EventListener* TouchListener = nullptr;
|
||||||
|
|
||||||
|
// std::vector<std::shared_ptr<CallbackCommand>> CallbackCommands{};
|
||||||
|
std::vector<std::shared_ptr<CustomCommand>> CustomCommands{};
|
||||||
|
Vector<ProgramState*> ProgramStates{};
|
||||||
|
|
||||||
|
SavedRenderStateData SavedRenderState{};
|
||||||
|
Vec2 ViewResolution = Vec2(1920, 1080);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts
|
||||||
|
static ImGui_ImplAndroid_Data* ImGui_ImplAndroid_GetBackendData()
|
||||||
|
{
|
||||||
|
return ImGui::GetCurrentContext() ? (ImGui_ImplAndroid_Data*)ImGui::GetIO().BackendPlatformUserData : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forward Declarations
|
||||||
|
static void ImGui_ImplAndroid_ShutdownPlatformInterface();
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
static bool ImGui_ImplAndroid_Init(GLView* window, bool install_callbacks)
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
IM_ASSERT(io.BackendPlatformUserData == NULL && "Already initialized a platform backend!");
|
||||||
|
|
||||||
|
// Setup backend capabilities flags
|
||||||
|
ImGui_ImplAndroid_Data* bd = IM_NEW(ImGui_ImplAndroid_Data)();
|
||||||
|
io.BackendPlatformUserData = (void*)bd;
|
||||||
|
io.BackendPlatformName = "imgui_impl_android";
|
||||||
|
//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)
|
||||||
|
|
||||||
|
bd->Window = window;
|
||||||
|
bd->Time = 0.0;
|
||||||
|
|
||||||
|
io.ClipboardUserData = bd->Window;
|
||||||
|
|
||||||
|
// Our mouse update function expect PlatformHandle to be filled for the main viewport
|
||||||
|
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||||
|
main_viewport->PlatformHandle = (void*)bd->Window;
|
||||||
|
|
||||||
|
io.AddFocusEvent(true);
|
||||||
|
|
||||||
|
auto* touchListener = EventListenerTouchOneByOne::create();
|
||||||
|
touchListener->setSwallowTouches(true);
|
||||||
|
touchListener->retain();
|
||||||
|
bd->TouchListener = touchListener;
|
||||||
|
|
||||||
|
touchListener->onTouchBegan = [](Touch* touch, Event* /*event*/) -> bool {
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
ImGui_ImplAndroid_Data* bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
auto location = touch->getLocationInView();
|
||||||
|
auto origin = bd->Window->getVisibleOrigin();
|
||||||
|
auto realX = location.x * bd->Window->getScaleX();
|
||||||
|
auto realY = (location.y - origin.y) * bd->Window->getScaleY();
|
||||||
|
realX /= io.DisplayFramebufferScale.x;
|
||||||
|
realY /= io.DisplayFramebufferScale.y;
|
||||||
|
io.AddMousePosEvent(realX, realY);
|
||||||
|
bd->LastValidMousePos = ImVec2(realX, realY);
|
||||||
|
io.AddMouseButtonEvent(0, true);
|
||||||
|
|
||||||
|
// We can't check if we're actually hovering over a ImGui element, since the
|
||||||
|
// AddMousePosEvent is not instant, it's queued. So, just return true here
|
||||||
|
// to indicate that we're handling this event.
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
touchListener->onTouchMoved = [](Touch* touch, Event* /*event*/) {
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
ImGui_ImplAndroid_Data* bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
auto location = touch->getLocationInView();
|
||||||
|
auto origin = bd->Window->getVisibleOrigin();
|
||||||
|
auto realX = location.x * bd->Window->getScaleX();
|
||||||
|
auto realY = (location.y - origin.y) * bd->Window->getScaleY();
|
||||||
|
realX /= io.DisplayFramebufferScale.x;
|
||||||
|
realY /= io.DisplayFramebufferScale.y;
|
||||||
|
io.AddMousePosEvent(realX, realY);
|
||||||
|
bd->LastValidMousePos = ImVec2(realX, realY);;
|
||||||
|
};
|
||||||
|
|
||||||
|
touchListener->onTouchEnded = [](Touch* touch, Event* /*event*/) {
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
ImGui_ImplAndroid_Data* bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
auto location = touch->getLocationInView();
|
||||||
|
auto origin = bd->Window->getVisibleOrigin();
|
||||||
|
auto realX = location.x * bd->Window->getScaleX();
|
||||||
|
auto realY = (location.y - origin.y) * bd->Window->getScaleY();
|
||||||
|
realX /= io.DisplayFramebufferScale.x;
|
||||||
|
realY /= io.DisplayFramebufferScale.y;
|
||||||
|
io.AddMousePosEvent(realX, realY);
|
||||||
|
bd->LastValidMousePos = ImVec2(realX, realY);;
|
||||||
|
io.AddMouseButtonEvent(0, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
touchListener->onTouchCancelled = [](Touch* touch, Event* /*event*/) {
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
ImGui_ImplAndroid_Data* bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
auto location = touch->getLocationInView();
|
||||||
|
auto origin = bd->Window->getVisibleOrigin();
|
||||||
|
auto realX = location.x * bd->Window->getScaleX();
|
||||||
|
auto realY = (location.y - origin.y) * bd->Window->getScaleY();
|
||||||
|
realX /= io.DisplayFramebufferScale.x;
|
||||||
|
realY /= io.DisplayFramebufferScale.y;
|
||||||
|
io.AddMousePosEvent(realX, realY);
|
||||||
|
bd->LastValidMousePos = ImVec2(realX, realY);
|
||||||
|
io.AddMouseButtonEvent(0, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(touchListener, 1);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAx_RenderPlatform()
|
||||||
|
{
|
||||||
|
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||||
|
{
|
||||||
|
ImGui::UpdatePlatformWindows();
|
||||||
|
ImGui::RenderPlatformWindowsDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplAndroid_Shutdown()
|
||||||
|
{
|
||||||
|
ImGui_ImplAndroid_Data* bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
IM_ASSERT(bd != NULL && "No platform backend to shutdown, or already shutdown?");
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
ImGui_ImplAndroid_ShutdownPlatformInterface();
|
||||||
|
|
||||||
|
io.BackendPlatformName = NULL;
|
||||||
|
io.BackendPlatformUserData = NULL;
|
||||||
|
|
||||||
|
IM_DELETE(bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplAndroid_NewFrame()
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
ImGui_ImplAndroid_Data* bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
IM_ASSERT(bd != NULL && "Did you call ImGui_ImplAndroid_InitForXXX()?");
|
||||||
|
|
||||||
|
// Setup display size (every frame to accommodate for window resizing)
|
||||||
|
int32_t window_width = bd->ViewResolution.width;
|
||||||
|
int32_t window_height = bd->ViewResolution.height;
|
||||||
|
int display_width = bd->Window->getFrameSize().width;
|
||||||
|
int display_height = bd->Window->getFrameSize().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 = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f);
|
||||||
|
bd->Time = current_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------
|
||||||
|
// 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..
|
||||||
|
//--------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Helper structure we store in the void* RenderUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||||
|
struct ImGui_ImplAndroid_ViewportData
|
||||||
|
{
|
||||||
|
GLView* Window;
|
||||||
|
bool WindowOwned;
|
||||||
|
int IgnoreWindowPosEventFrame;
|
||||||
|
int IgnoreWindowSizeEventFrame;
|
||||||
|
|
||||||
|
ImGui_ImplAndroid_ViewportData() { Window = NULL; WindowOwned = false; IgnoreWindowSizeEventFrame = IgnoreWindowPosEventFrame = -1; }
|
||||||
|
~ImGui_ImplAndroid_ViewportData() { IM_ASSERT(Window == NULL); }
|
||||||
|
};
|
||||||
|
|
||||||
|
static void ImGui_ImplAndroid_WindowCloseCallback(GLView* window)
|
||||||
|
{
|
||||||
|
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window))
|
||||||
|
viewport->PlatformRequestClose = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplAndroid_ShutdownPlatformInterface()
|
||||||
|
{
|
||||||
|
ImGui::DestroyPlatformWindows();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////// axmol spec /////////////////////////
|
||||||
|
|
||||||
|
#define AX_PTR_CAST(v, pointer_type) reinterpret_cast<pointer_type>(v)
|
||||||
|
|
||||||
|
|
||||||
|
// fps macro
|
||||||
|
#define AX_IMGUI_DEFAULT_DELTA (1 / 60.f)
|
||||||
|
#define AX_IMGUI_MIN_DELTA (1 / 1000.f)
|
||||||
|
#define AX_IMGUI_MAX_DELTA (1 / 30.f)
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
GlfwClientApi_Axmol = 0xadee,
|
||||||
|
};
|
||||||
|
|
||||||
|
// axmol spec
|
||||||
|
bool ImGui_ImplAndroid_InitForAx(GLView* window, bool install_callbacks)
|
||||||
|
{
|
||||||
|
return ImGui_ImplAndroid_Init(window, install_callbacks);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ImGui_ImplAx_Data
|
||||||
|
{
|
||||||
|
// axmol spec data
|
||||||
|
|
||||||
|
ImGuiImplCocos2dxLoadFontFun LoadCustomFont = nullptr;
|
||||||
|
void* LoadCustomFontUserData = nullptr;
|
||||||
|
|
||||||
|
ProgramInfoData ProgramInfo{};
|
||||||
|
ProgramInfoData ProgramFontInfo{};
|
||||||
|
bool FontDeviceObjectsDirty = false;
|
||||||
|
Texture2D* FontTexture = nullptr;
|
||||||
|
Mat4 Projection;
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<CallbackCommand>> CallbackCommands{};
|
||||||
|
std::vector<std::shared_ptr<CustomCommand>> CustomCommands{};
|
||||||
|
Vector<ProgramState*> ProgramStates{};
|
||||||
|
|
||||||
|
SavedRenderStateData SavedRenderState{};
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool ImGui_ImplAx_CreateFontsTexture();
|
||||||
|
static void ImGui_ImplAx_DestroyFontsTexture();
|
||||||
|
static void ImGui_ImplAx_DestroyDeviceObjects();
|
||||||
|
static bool ImGui_ImplAx_CreateDeviceObjects();
|
||||||
|
static void ImGui_ImplAx_RenderWindow(ImGuiViewport* viewport, void*);
|
||||||
|
static void AddRendererCommand(const std::function<void()>& f);
|
||||||
|
|
||||||
|
|
||||||
|
static bool ImGui_ImplAx_createShaderPrograms();
|
||||||
|
static void ImGui_ImplAx_Renderer_RenderWindow(ImGuiViewport* viewport, void*);
|
||||||
|
|
||||||
|
static void ImGui_ImplAx_InitPlatformInterface()
|
||||||
|
{
|
||||||
|
// Register platform interface (will be coupled with a renderer interface)
|
||||||
|
ImGui_ImplAndroid_Data* bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
|
||||||
|
platform_io.Renderer_RenderWindow = ImGui_ImplAx_Renderer_RenderWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplAx_Init()
|
||||||
|
{
|
||||||
|
auto bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
auto& io = ImGui::GetIO();
|
||||||
|
io.BackendRendererUserData = (void*)bd;
|
||||||
|
io.BackendRendererName = "imgui_impl_axmol";
|
||||||
|
io.BackendFlags |=
|
||||||
|
ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||||
|
// axmol spec: disable auto load and save
|
||||||
|
io.IniFilename = nullptr;
|
||||||
|
|
||||||
|
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||||
|
ImGui_ImplAx_InitPlatformInterface();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplAx_Shutdown()
|
||||||
|
{
|
||||||
|
ImGui_ImplAx_DestroyDeviceObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAx_NewFrame() {
|
||||||
|
auto bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
//bd->CallbackCommands.clear();
|
||||||
|
bd->CustomCommands.clear();
|
||||||
|
bd->ProgramStates.clear();
|
||||||
|
|
||||||
|
if (!bd->FontTexture)
|
||||||
|
ImGui_ImplAx_CreateDeviceObjects();
|
||||||
|
else if (bd->FontDeviceObjectsDirty)
|
||||||
|
{ // recreate device objects, fonts also should be device objects
|
||||||
|
ImGui_ImplAx_DestroyDeviceObjects();
|
||||||
|
ImGui_ImplAx_CreateDeviceObjects();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAx_SetCustomFontLoader(ImGuiImplCocos2dxLoadFontFun fun, void* userdata)
|
||||||
|
{
|
||||||
|
auto bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
bd->LoadCustomFont = fun;
|
||||||
|
bd->LoadCustomFontUserData = userdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMGUI_IMPL_API void* ImGui_ImplAx_GetFontsTexture()
|
||||||
|
{
|
||||||
|
auto bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
return bd->FontTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAx_SetDeviceObjectsDirty()
|
||||||
|
{
|
||||||
|
auto bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
bd->FontDeviceObjectsDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAx_SetViewResolution(float width, float height)
|
||||||
|
{
|
||||||
|
auto bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
bd->ViewResolution = Vec2(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ImGui_ImplAx_CreateDeviceObjects()
|
||||||
|
{
|
||||||
|
auto bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
if (bd->LoadCustomFont)
|
||||||
|
bd->LoadCustomFont(bd->LoadCustomFontUserData);
|
||||||
|
|
||||||
|
ImGui_ImplAx_createShaderPrograms();
|
||||||
|
ImGui_ImplAx_CreateFontsTexture();
|
||||||
|
|
||||||
|
bd->FontDeviceObjectsDirty = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplAx_DestroyDeviceObjects()
|
||||||
|
{
|
||||||
|
auto bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
AX_SAFE_RELEASE_NULL(bd->ProgramInfo.program);
|
||||||
|
AX_SAFE_RELEASE_NULL(bd->ProgramFontInfo.program);
|
||||||
|
AX_SAFE_RELEASE_NULL(bd->TouchListener);
|
||||||
|
|
||||||
|
ImGui_ImplAx_DestroyFontsTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ImGui_ImplAx_createShaderPrograms()
|
||||||
|
{
|
||||||
|
auto vertex_shader =
|
||||||
|
"uniform mat4 u_MVPMatrix;\n"
|
||||||
|
"attribute vec2 a_position;\n"
|
||||||
|
"attribute vec2 a_texCoord;\n"
|
||||||
|
"attribute vec4 a_color;\n"
|
||||||
|
"varying vec2 v_texCoord;\n"
|
||||||
|
"varying vec4 v_fragmentColor;\n"
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" v_texCoord = a_texCoord;\n"
|
||||||
|
" v_fragmentColor = a_color;\n"
|
||||||
|
" gl_Position = u_MVPMatrix * vec4(a_position.xy, 0.0, 1.0);\n"
|
||||||
|
"}\n";
|
||||||
|
auto fragment_shader =
|
||||||
|
"#ifdef GL_ES\n"
|
||||||
|
" precision mediump float;\n"
|
||||||
|
"#endif\n"
|
||||||
|
"uniform sampler2D u_tex0;\n"
|
||||||
|
"varying vec2 v_texCoord;\n"
|
||||||
|
"varying vec4 v_fragmentColor;\n"
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" gl_FragColor = v_fragmentColor * texture2D(u_tex0, v_texCoord);\n"
|
||||||
|
"}\n";
|
||||||
|
auto fragment_shader_font =
|
||||||
|
"#ifdef GL_ES\n"
|
||||||
|
" precision mediump float;\n"
|
||||||
|
"#endif\n"
|
||||||
|
"uniform sampler2D u_tex0;\n"
|
||||||
|
"varying vec2 v_texCoord;\n"
|
||||||
|
"varying vec4 v_fragmentColor;\n"
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" float a = texture2D(u_tex0, v_texCoord).a;\n"
|
||||||
|
" gl_FragColor = vec4(v_fragmentColor.rgb, v_fragmentColor.a * a);\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
auto bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
|
||||||
|
AX_SAFE_RELEASE(bd->ProgramInfo.program);
|
||||||
|
AX_SAFE_RELEASE(bd->ProgramFontInfo.program);
|
||||||
|
bd->ProgramInfo.program = backend::Device::getInstance()->newProgram(vertex_shader, fragment_shader);
|
||||||
|
bd->ProgramFontInfo.program = backend::Device::getInstance()->newProgram(vertex_shader, fragment_shader_font);
|
||||||
|
IM_ASSERT(bd->ProgramInfo.program);
|
||||||
|
IM_ASSERT(bd->ProgramFontInfo.program);
|
||||||
|
if (!bd->ProgramInfo.program || !bd->ProgramFontInfo.program)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (auto& p : {&bd->ProgramInfo, &bd->ProgramFontInfo})
|
||||||
|
{
|
||||||
|
p->texture = p->program->getUniformLocation(TEXTURE);
|
||||||
|
p->projection = p->program->getUniformLocation(MVP_MATRIX);
|
||||||
|
p->position = p->program->getAttributeLocation(POSITION);
|
||||||
|
p->uv = p->program->getAttributeLocation(TEXCOORD);
|
||||||
|
p->color = p->program->getAttributeLocation(COLOR);
|
||||||
|
IM_ASSERT(bool(p->texture));
|
||||||
|
IM_ASSERT(bool(p->projection));
|
||||||
|
IM_ASSERT(p->position >= 0);
|
||||||
|
IM_ASSERT(p->uv >= 0);
|
||||||
|
IM_ASSERT(p->color >= 0);
|
||||||
|
auto& layout = p->layout;
|
||||||
|
layout.setAttribute("a_position", p->position, VertexFormat::FLOAT2, 0, false);
|
||||||
|
layout.setAttribute("a_texCoord", p->uv, VertexFormat::FLOAT2, offsetof(ImDrawVert, uv), false);
|
||||||
|
layout.setAttribute("a_color", p->color, VertexFormat::UBYTE4, offsetof(ImDrawVert, col), true);
|
||||||
|
layout.setStride(sizeof(ImDrawVert));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGui_ImplAx_CreateFontsTexture()
|
||||||
|
{
|
||||||
|
auto bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
// Build texture atlas
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
unsigned char* pixels;
|
||||||
|
int width, height;
|
||||||
|
// Load as RGBA 32-bits (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.
|
||||||
|
io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height);
|
||||||
|
|
||||||
|
AX_SAFE_RELEASE(bd->FontTexture);
|
||||||
|
bd->FontTexture = new Texture2D();
|
||||||
|
|
||||||
|
bd->FontTexture->setAntiAliasTexParameters();
|
||||||
|
bd->FontTexture->initWithData(pixels, width * height, backend::PixelFormat::A8, width, height);
|
||||||
|
io.Fonts->TexID = (ImTextureID)bd->FontTexture;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAx_DestroyFontsTexture()
|
||||||
|
{
|
||||||
|
auto bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
if (bd->FontTexture)
|
||||||
|
{
|
||||||
|
ImGui::GetIO().Fonts->TexID = nullptr;
|
||||||
|
AX_SAFE_RELEASE_NULL(bd->FontTexture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddRendererCommand(const std::function<void()>& f)
|
||||||
|
{
|
||||||
|
auto bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
const auto renderer = Director::getInstance()->getRenderer();
|
||||||
|
auto cmd = renderer->nextCallbackCommand();
|
||||||
|
cmd->init(0.f);
|
||||||
|
cmd->func = f;
|
||||||
|
renderer->addCommand(cmd);
|
||||||
|
//bd->CallbackCommands.push_back(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplAx_SaveRenderState(ax::Renderer* renderer)
|
||||||
|
{
|
||||||
|
AddRendererCommand([renderer]() {
|
||||||
|
auto bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
bd->SavedRenderState.cull = renderer->getCullMode();
|
||||||
|
bd->SavedRenderState.vp = renderer->getViewport();
|
||||||
|
bd->SavedRenderState.scissorTest = renderer->getScissorTest();
|
||||||
|
bd->SavedRenderState.scissorRect = renderer->getScissorRect();
|
||||||
|
bd->SavedRenderState.depthTest = renderer->getDepthTest();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplAx_SetupRenderState(ax::Renderer* renderer,
|
||||||
|
ImDrawData* draw_data,
|
||||||
|
int fb_width,
|
||||||
|
int fb_height)
|
||||||
|
{
|
||||||
|
AddRendererCommand([=]() {
|
||||||
|
renderer->setCullMode(backend::CullMode::NONE);
|
||||||
|
renderer->setDepthTest(false);
|
||||||
|
renderer->setScissorTest(true);
|
||||||
|
renderer->setViewPort(0, 0, fb_width, fb_height);
|
||||||
|
});
|
||||||
|
|
||||||
|
const auto L = draw_data->DisplayPos.x;
|
||||||
|
const auto R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||||
|
const auto T = draw_data->DisplayPos.y;
|
||||||
|
const auto B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
|
||||||
|
|
||||||
|
auto bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
Mat4::createOrthographicOffCenter(L, R, B, T, -1.f, 1.f, &bd->Projection);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplAx_RestoreRenderState(ax::Renderer* renderer)
|
||||||
|
{
|
||||||
|
AddRendererCommand([renderer]() {
|
||||||
|
auto bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
renderer->setCullMode(bd->SavedRenderState.cull);
|
||||||
|
auto& vp = bd->SavedRenderState.vp;
|
||||||
|
renderer->setViewPort(vp.x, vp.y, vp.w, vp.h);
|
||||||
|
renderer->setScissorTest(bd->SavedRenderState.scissorTest);
|
||||||
|
auto& sc = bd->SavedRenderState.scissorRect;
|
||||||
|
renderer->setScissorRect(sc.x, sc.y, sc.width, sc.height);
|
||||||
|
renderer->setDepthTest(bd->SavedRenderState.depthTest);
|
||||||
|
|
||||||
|
// apply raster state
|
||||||
|
renderer->beginRenderPass();
|
||||||
|
renderer->endRenderPass();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAx_RenderDrawData(ImDrawData* draw_data)
|
||||||
|
{
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
const auto renderer = Director::getInstance()->getRenderer();
|
||||||
|
|
||||||
|
ImGui_ImplAx_SaveRenderState(renderer);
|
||||||
|
|
||||||
|
ImGui_ImplAx_SetupRenderState(renderer, draw_data, 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
|
||||||
|
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||||
|
{
|
||||||
|
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||||
|
size_t ibuffer_offset = 0;
|
||||||
|
|
||||||
|
// Upload vertex/index buffers
|
||||||
|
const auto vsize = cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);
|
||||||
|
IM_ASSERT(vsize > 0);
|
||||||
|
auto vbuffer = backend::Device::getInstance()->newBuffer(vsize, BufferType::VERTEX, BufferUsage::STATIC);
|
||||||
|
vbuffer->autorelease();
|
||||||
|
vbuffer->updateData(cmd_list->VtxBuffer.Data, vsize);
|
||||||
|
const auto isize = cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx);
|
||||||
|
IM_ASSERT(isize > 0);
|
||||||
|
auto ibuffer = backend::Device::getInstance()->newBuffer(isize, BufferType::INDEX, BufferUsage::STATIC);
|
||||||
|
ibuffer->autorelease();
|
||||||
|
ibuffer->updateData(cmd_list->IdxBuffer.Data, isize);
|
||||||
|
|
||||||
|
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||||
|
{
|
||||||
|
const ImDrawCmd* pcmd = &cmd_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_ImplAx_SetupRenderState(renderer, draw_data, fb_width, fb_height);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddRendererCommand([=]() { pcmd->UserCallback(cmd_list, pcmd); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
|
ImVec4 clip_rect;
|
||||||
|
clip_rect.x = (pcmd->ClipRect.x - clip_off.x) * clip_scale.x;
|
||||||
|
clip_rect.y = (pcmd->ClipRect.y - clip_off.y) * clip_scale.y;
|
||||||
|
clip_rect.z = (pcmd->ClipRect.z - clip_off.x) * clip_scale.x;
|
||||||
|
clip_rect.w = (pcmd->ClipRect.w - clip_off.y) * clip_scale.y;
|
||||||
|
|
||||||
|
if (clip_rect.x < fb_width && clip_rect.y < fb_height && clip_rect.z >= 0.0f && clip_rect.w >= 0.0f)
|
||||||
|
{
|
||||||
|
// Apply scissor/clipping rectangle
|
||||||
|
AddRendererCommand([=]() {
|
||||||
|
renderer->setScissorRect(clip_rect.x, fb_height - clip_rect.w, clip_rect.z - clip_rect.x,
|
||||||
|
clip_rect.w - clip_rect.y);
|
||||||
|
});
|
||||||
|
|
||||||
|
auto bd = ImGui_ImplAndroid_GetBackendData();
|
||||||
|
|
||||||
|
if (typeid(*((Ref*)pcmd->TextureId)) == typeid(Texture2D))
|
||||||
|
{
|
||||||
|
auto tex = AX_PTR_CAST(pcmd->TextureId, Texture2D*);
|
||||||
|
auto cmd = std::make_shared<CustomCommand>();
|
||||||
|
bd->CustomCommands.push_back(cmd);
|
||||||
|
cmd->init(0.f, BlendFunc::ALPHA_NON_PREMULTIPLIED);
|
||||||
|
const auto pinfo = tex == bd->FontTexture ? &bd->ProgramFontInfo : &bd->ProgramInfo;
|
||||||
|
// create new ProgramState
|
||||||
|
auto state = new ProgramState(pinfo->program);
|
||||||
|
state->autorelease();
|
||||||
|
bd->ProgramStates.pushBack(state);
|
||||||
|
auto& desc = cmd->getPipelineDescriptor();
|
||||||
|
desc.programState = state;
|
||||||
|
// setup attributes for ImDrawVert
|
||||||
|
desc.programState->setVertexLayout(pinfo->layout);
|
||||||
|
desc.programState->setUniform(pinfo->projection, &bd->Projection, sizeof(Mat4));
|
||||||
|
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
|
||||||
|
cmd->setIndexBuffer(ibuffer, IMGUI_INDEX_FORMAT);
|
||||||
|
cmd->setVertexBuffer(vbuffer);
|
||||||
|
cmd->setDrawType(CustomCommand::DrawType::ELEMENT);
|
||||||
|
cmd->setPrimitiveType(PrimitiveType::TRIANGLE);
|
||||||
|
cmd->setIndexDrawInfo(ibuffer_offset, pcmd->ElemCount);
|
||||||
|
renderer->addCommand(cmd.get());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto node = AX_PTR_CAST(pcmd->TextureId, Node*);
|
||||||
|
const auto tr = node->getNodeToParentTransform();
|
||||||
|
node->setVisible(true);
|
||||||
|
node->setNodeToParentTransform(tr);
|
||||||
|
const auto& proj =
|
||||||
|
Director::getInstance()->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);
|
||||||
|
node->visit(Director::getInstance()->getRenderer(), proj.getInversed() * bd->Projection, 0);
|
||||||
|
node->setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ibuffer_offset += pcmd->ElemCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui_ImplAx_RestoreRenderState(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------
|
||||||
|
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||||
|
// This is an _advanced_ and _optional_ feature, allowing the back-end 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..
|
||||||
|
//--------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static void ImGui_ImplAx_Renderer_RenderWindow(ImGuiViewport* viewport, void*)
|
||||||
|
{
|
||||||
|
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
||||||
|
{
|
||||||
|
const auto renderer = Director::getInstance()->getRenderer();
|
||||||
|
renderer->clear(ClearFlag::COLOR, {0, 0, 0, 1}, 1, 0, 0);
|
||||||
|
}
|
||||||
|
ImGui_ImplAx_RenderDrawData(viewport->DrawData);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
#pragma once
|
||||||
|
#include "imgui.h"
|
||||||
|
#include "platform/CCGLView.h"
|
||||||
|
|
||||||
|
struct ANativeWindow;
|
||||||
|
struct AInputEvent;
|
||||||
|
|
||||||
|
typedef void (*ImGuiImplCocos2dxLoadFontFun)(void* userdata);
|
||||||
|
|
||||||
|
/// ImGui glfw APIs
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplAndroid_InitForAx(ax::GLView* window, bool install_callbacks);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAndroid_Shutdown();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAndroid_NewFrame();
|
||||||
|
|
||||||
|
/// ImGui axmol render APIs
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAx_Init();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAx_Shutdown();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAx_NewFrame();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAx_RenderDrawData(ImDrawData* draw_data);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAx_RenderPlatform();
|
||||||
|
|
||||||
|
// Get FontTexture object ax::Texture2D*
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAx_SetCustomFontLoader(ImGuiImplCocos2dxLoadFontFun fun, void* userdata);
|
||||||
|
IMGUI_IMPL_API void* ImGui_ImplAx_GetFontsTexture();
|
||||||
|
|
||||||
|
// Sets Device objects dirty
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAx_SetDeviceObjectsDirty();
|
||||||
|
|
||||||
|
// Set the required view resolution for the UI
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplAx_SetViewResolution(float width, float height);
|
|
@ -6,7 +6,7 @@
|
||||||
USING_NS_AX;
|
USING_NS_AX;
|
||||||
USING_NS_AX_EXT;
|
USING_NS_AX_EXT;
|
||||||
|
|
||||||
#if defined(AX_PLATFORM_PC)
|
#if defined(AX_PLATFORM_PC) || (AX_TARGET_PLATFORM == AX_PLATFORM_ANDROID)
|
||||||
|
|
||||||
static bool show_test_window = true;
|
static bool show_test_window = true;
|
||||||
static bool show_another_window = true;
|
static bool show_another_window = true;
|
||||||
|
@ -14,11 +14,7 @@ static ImVec4 clear_color = ImColor(114, 144, 154);
|
||||||
|
|
||||||
ImGuiTests::ImGuiTests()
|
ImGuiTests::ImGuiTests()
|
||||||
{
|
{
|
||||||
// Resize (expand) window
|
ImGuiPresenter::getInstance()->setViewResolution(1280, 720);
|
||||||
static Size resourceSize(1280, 720);
|
|
||||||
auto director = Director::getInstance();
|
|
||||||
GLViewImpl* view = (GLViewImpl*)Director::getInstance()->getOpenGLView();
|
|
||||||
view->setWindowed(resourceSize.width, resourceSize.height);
|
|
||||||
|
|
||||||
ADD_TEST_CASE(ImGuiTest);
|
ADD_TEST_CASE(ImGuiTest);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include "cocos2d.h"
|
#include "cocos2d.h"
|
||||||
#include "../BaseTest.h"
|
#include "../BaseTest.h"
|
||||||
|
|
||||||
#if defined(AX_PLATFORM_PC)
|
#if defined(AX_PLATFORM_PC) || (AX_TARGET_PLATFORM == AX_PLATFORM_ANDROID)
|
||||||
|
|
||||||
DEFINE_TEST_SUITE(ImGuiTests);
|
DEFINE_TEST_SUITE(ImGuiTests);
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ public:
|
||||||
RootTests()
|
RootTests()
|
||||||
{
|
{
|
||||||
// addTest("Node: Scene3D", [](){return new Scene3DTests(); });
|
// addTest("Node: Scene3D", [](){return new Scene3DTests(); });
|
||||||
#if defined(AX_PLATFORM_PC)
|
#if defined(AX_PLATFORM_PC) || (AX_TARGET_PLATFORM == AX_PLATFORM_ANDROID)
|
||||||
addTest("ImGui", []() { return new ImGuiTests(); });
|
addTest("ImGui", []() { return new ImGuiTests(); });
|
||||||
#endif
|
#endif
|
||||||
addTest("Texture2D", []() { return new Texture2DTests(); });
|
addTest("Texture2D", []() { return new Texture2DTests(); });
|
||||||
|
|
|
@ -119,7 +119,7 @@
|
||||||
#include "ZwoptexTest/ZwoptexTest.h"
|
#include "ZwoptexTest/ZwoptexTest.h"
|
||||||
#include "SpriteFrameCacheTest/SpriteFrameCacheTest.h"
|
#include "SpriteFrameCacheTest/SpriteFrameCacheTest.h"
|
||||||
#include "ZipTest/ZipTests.h"
|
#include "ZipTest/ZipTests.h"
|
||||||
#if defined(AX_PLATFORM_PC)
|
#if defined(AX_PLATFORM_PC) || (AX_TARGET_PLATFORM == AX_PLATFORM_ANDROID)
|
||||||
# include "ImGuiTest/ImGuiTest.h"
|
# include "ImGuiTest/ImGuiTest.h"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue