mirror of https://github.com/axmolengine/axmol.git
Refine extension ImGui, and rename director to ImGuiEXT
This commit is contained in:
parent
e3e3352440
commit
cc2c524573
|
@ -15,7 +15,7 @@ option(BUILD_EXTENSION_COCOSTUDIO "Build extension cocostudio" ON)
|
||||||
|
|
||||||
option(BUILD_EXTENSION_FAIRYGUI "Build extension FairyGUI" ON)
|
option(BUILD_EXTENSION_FAIRYGUI "Build extension FairyGUI" ON)
|
||||||
|
|
||||||
option(BUILD_EXTENSION_IMGUI "Build extension ImGui" OFF)
|
option(BUILD_EXTENSION_IMGUIEXT "Build extension ImGuiEXT" OFF)
|
||||||
|
|
||||||
function(setup_cocos_extension_config target_name)
|
function(setup_cocos_extension_config target_name)
|
||||||
if(ANDROID)
|
if(ANDROID)
|
||||||
|
@ -73,8 +73,8 @@ if(BUILD_EXTENSION_FAIRYGUI)
|
||||||
add_subdirectory(fairygui)
|
add_subdirectory(fairygui)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(BUILD_EXTENSION_IMGUI)
|
if(BUILD_EXTENSION_IMGUIEXT)
|
||||||
add_subdirectory(ImGui)
|
add_subdirectory(ImGuiEXT)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
message(STATUS "CC_EXTENSION_LIBS:${CC_EXTENSION_LIBS}")
|
message(STATUS "CC_EXTENSION_LIBS:${CC_EXTENSION_LIBS}")
|
||||||
|
|
|
@ -1,65 +0,0 @@
|
||||||
#include "CCImGuiLayer.h"
|
|
||||||
#include "imgui/imgui.h"
|
|
||||||
#include "imgui_impl_cocos2dx.h"
|
|
||||||
#include "CCImGuiEXT.h"
|
|
||||||
|
|
||||||
NS_CC_EXT_BEGIN
|
|
||||||
|
|
||||||
bool ImGuiLayer::init()
|
|
||||||
{
|
|
||||||
if (!Layer::init() || !ImGuiEXT::getInstance())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
#ifdef CC_PLATFORM_PC
|
|
||||||
// note: when at the first click to focus the window, this will not take effect
|
|
||||||
auto listener = EventListenerTouchOneByOne::create();
|
|
||||||
listener->setSwallowTouches(true);
|
|
||||||
listener->onTouchBegan = [this](Touch* touch, Event*) -> bool {
|
|
||||||
if (!_visible)
|
|
||||||
return false;
|
|
||||||
return ImGui::IsAnyWindowHovered();
|
|
||||||
};
|
|
||||||
getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
|
|
||||||
|
|
||||||
// add by halx99
|
|
||||||
auto stopAnyMouse = [=](EventMouse* event) {
|
|
||||||
if (ImGui::IsAnyWindowHovered()) {
|
|
||||||
event->stopPropagation();
|
|
||||||
cocos2d::log("!!!EventMouse should stop by ImGuiLayer");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
auto mouseListener = EventListenerMouse::create();
|
|
||||||
mouseListener->onMouseDown = mouseListener->onMouseUp = stopAnyMouse;
|
|
||||||
getEventDispatcher()->addEventListenerWithSceneGraphPriority(mouseListener, this);
|
|
||||||
#endif
|
|
||||||
// add an empty sprite to avoid render problem
|
|
||||||
const auto sp = Sprite::create();
|
|
||||||
sp->setGlobalZOrder(1);
|
|
||||||
sp->setOpacity(0);
|
|
||||||
addChild(sp, 1);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGuiLayer::visit(Renderer* renderer, const Mat4 &parentTransform, uint32_t parentFlags)
|
|
||||||
{
|
|
||||||
Layer::visit(renderer, parentTransform, parentFlags);
|
|
||||||
if(_visible) frame();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGuiLayer::frame()
|
|
||||||
{
|
|
||||||
// create frame
|
|
||||||
ImGui_ImplCocos2dx_NewFrame();
|
|
||||||
|
|
||||||
// draw all gui
|
|
||||||
ImGuiEXT::getInstance()->onDraw();
|
|
||||||
|
|
||||||
// render
|
|
||||||
ImGui::Render();
|
|
||||||
|
|
||||||
ImGui_ImplCocos2dx_RenderDrawData(ImGui::GetDrawData());
|
|
||||||
ImGui_ImplCocos2dx_RenderPlatform();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_CC_EXT_END
|
|
|
@ -1,18 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "cocos2d.h"
|
|
||||||
#include "ExtensionMacros.h"
|
|
||||||
|
|
||||||
NS_CC_EXT_BEGIN
|
|
||||||
|
|
||||||
class ImGuiLayer : public Layer
|
|
||||||
{
|
|
||||||
CC_CONSTRUCTOR_ACCESS:
|
|
||||||
virtual bool init() override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void visit(cocos2d::Renderer *renderer, const cocos2d::Mat4& parentTransform, uint32_t parentFlags) override;
|
|
||||||
|
|
||||||
void frame();
|
|
||||||
};
|
|
||||||
|
|
||||||
NS_CC_EXT_END
|
|
|
@ -1,8 +0,0 @@
|
||||||
# egnx-imgui-ext
|
|
||||||
Sync from https://github.com/Xrysnow/cocos2d-x-imgui and do a little changes
|
|
||||||
|
|
||||||
## How to use
|
|
||||||
Same with https://github.com/Xrysnow/cocos2d-x-imgui but do a little changes:
|
|
||||||
* ```CCIMGUI``` --> ```cocos2d::extension::ImGuiEXT```
|
|
||||||
* ```ImGuiLayer``` --> ```cocos2d::extension::ImGuiLayer```
|
|
||||||
* And no lua bindings currently
|
|
|
@ -3,6 +3,118 @@
|
||||||
|
|
||||||
NS_CC_EXT_BEGIN
|
NS_CC_EXT_BEGIN
|
||||||
|
|
||||||
|
static uint32_t fourccValue(const std::string& str) {
|
||||||
|
if (str.empty() || str[0] != '#') return (uint32_t)-1;
|
||||||
|
uint32_t value = 0;
|
||||||
|
memcpy(&value, str.c_str() + 1, std::min(sizeof(value), str.size() - 1));
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ImGuiEXTRenderer : public Layer
|
||||||
|
{
|
||||||
|
CC_CONSTRUCTOR_ACCESS:
|
||||||
|
bool initWithImGuiEXT(ImGuiEXT* guiext)
|
||||||
|
{
|
||||||
|
if (!Layer::init())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
_imguiext = guiext; // weak ref the singleton instance
|
||||||
|
|
||||||
|
#ifdef CC_PLATFORM_PC
|
||||||
|
// note: when at the first click to focus the window, this will not take effect
|
||||||
|
auto listener = EventListenerTouchOneByOne::create();
|
||||||
|
listener->setSwallowTouches(true);
|
||||||
|
listener->onTouchBegan = [this](Touch* touch, Event*) -> bool {
|
||||||
|
if (!_visible)
|
||||||
|
return false;
|
||||||
|
return ImGui::IsAnyWindowHovered();
|
||||||
|
};
|
||||||
|
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
|
||||||
|
|
||||||
|
// add by halx99
|
||||||
|
auto stopAnyMouse = [=](EventMouse* event) {
|
||||||
|
if (ImGui::IsAnyWindowHovered()) {
|
||||||
|
event->stopPropagation();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
auto mouseListener = EventListenerMouse::create();
|
||||||
|
mouseListener->onMouseDown = mouseListener->onMouseUp = stopAnyMouse;
|
||||||
|
_eventDispatcher->addEventListenerWithSceneGraphPriority(mouseListener, this);
|
||||||
|
#endif
|
||||||
|
// add an empty sprite to avoid render problem
|
||||||
|
// const auto sp = Sprite::create();
|
||||||
|
// sp->setGlobalZOrder(1);
|
||||||
|
// sp->setOpacity(0);
|
||||||
|
// addChild(sp, 1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There a 3 choice for schedule frame for ImGui render loop
|
||||||
|
* a. at visit/draw to call beginFrame/endFrame, but at ImGui loop, we can't game object and add to Scene directly, will cause damage iterator
|
||||||
|
* b. scheduleUpdate at onEnter to call beginFrame, at visit/draw to call endFrame, it's solve iterator damage problem, but when director is paused
|
||||||
|
* the director will stop call 'update' function of Scheduler
|
||||||
|
* And need modify engine code to call _scheduler->update(_deltaTime) even director is paused, pass 0 for update
|
||||||
|
* c. Director::EVENT_BEFORE_DRAW call beginFrame, EVENT_AFTER_VISIT call endFrame
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* !!!All of methods, we should calculate delta at imgui_impl_cocos2dx manually
|
||||||
|
*/
|
||||||
|
_eventDispatcher->addCustomEventListener(Director::EVENT_BEFORE_DRAW, [=](EventCustom*) { beginFrame(); });
|
||||||
|
_eventDispatcher->addCustomEventListener(Director::EVENT_AFTER_VISIT, [=](EventCustom*) { endFrame(); });
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ImGuiEXTRenderer()
|
||||||
|
{
|
||||||
|
_eventDispatcher->removeCustomEventListeners(Director::EVENT_AFTER_VISIT);
|
||||||
|
_eventDispatcher->removeCustomEventListeners(Director::EVENT_BEFORE_DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/*void onEnter() override
|
||||||
|
{
|
||||||
|
Layer::onEnter();
|
||||||
|
scheduleUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void update(float dt) {
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*virtual void draw(cocos2d::Renderer* renderer, const cocos2d::Mat4& parentTransform, uint32_t parentFlags) override
|
||||||
|
{
|
||||||
|
Layer::draw(renderer, parentTransform, parentFlags);
|
||||||
|
|
||||||
|
endFrame();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* begin ImGui frame and draw ImGui stubs
|
||||||
|
*/
|
||||||
|
void beginFrame()
|
||||||
|
{
|
||||||
|
// create frame
|
||||||
|
ImGui_ImplCocos2dx_NewFrame();
|
||||||
|
|
||||||
|
// draw all gui
|
||||||
|
_imguiext->update();
|
||||||
|
|
||||||
|
// render
|
||||||
|
ImGui::Render();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* flush ImGui draw data to engine
|
||||||
|
*/
|
||||||
|
void endFrame() {
|
||||||
|
ImGui_ImplCocos2dx_RenderDrawData(ImGui::GetDrawData());
|
||||||
|
ImGui_ImplCocos2dx_RenderPlatform();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiEXT* _imguiext = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
static ImGuiEXT* _instance = nullptr;
|
static ImGuiEXT* _instance = nullptr;
|
||||||
std::function<void(ImGuiEXT*)> ImGuiEXT::_onInit;
|
std::function<void(ImGuiEXT*)> ImGuiEXT::_onInit;
|
||||||
|
|
||||||
|
@ -27,8 +139,8 @@ void ImGuiEXT::destroyInstance()
|
||||||
{
|
{
|
||||||
if (_instance)
|
if (_instance)
|
||||||
{
|
{
|
||||||
delete _instance;
|
|
||||||
ImGui_ImplCocos2dx_Shutdown();
|
ImGui_ImplCocos2dx_Shutdown();
|
||||||
|
delete _instance;
|
||||||
_instance = nullptr;
|
_instance = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,30 +150,46 @@ void ImGuiEXT::setOnInit(const std::function<void(ImGuiEXT*)>& callBack)
|
||||||
_onInit = callBack;
|
_onInit = callBack;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::onDraw()
|
void ImGuiEXT::update()
|
||||||
{
|
{ // drived by ImGuiEXTRenderer
|
||||||
|
|
||||||
// clear things from last frame
|
// clear things from last frame
|
||||||
usedCCRefIdMap.clear();
|
usedCCRefIdMap.clear();
|
||||||
usedCCRef.clear();
|
usedCCRef.clear();
|
||||||
// drawing commands
|
// drawing commands
|
||||||
auto iter = _callPiplines.begin();
|
for (auto& pipline : _renderPiplines)
|
||||||
for (; iter != _callPiplines.end(); ++iter)
|
pipline.second.frame();
|
||||||
{
|
|
||||||
iter->second();
|
|
||||||
}
|
|
||||||
// commands will be processed after update
|
// commands will be processed after update
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::addCallback(const std::function<void()>& callBack, const std::string& name)
|
bool ImGuiEXT::addRenderLoop(const std::string& id, Scene* scene, std::function<void()> onFrame)
|
||||||
{
|
{
|
||||||
_callPiplines[name] = callBack;
|
// TODO: check whether exist
|
||||||
|
auto fourccId = fourccValue(id);
|
||||||
|
if (_renderPiplines.find(fourccId) != _renderPiplines.end())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiEXT::removeCallback(const std::string& name)
|
auto renderer = utils::newInstance<ImGuiEXTRenderer>(&ImGuiEXTRenderer::initWithImGuiEXT, this);
|
||||||
|
scene->addChild(renderer, INT_MAX, fourccId);
|
||||||
|
_renderPiplines.emplace(fourccId, RenderPipline{ renderer, std::move(onFrame) });
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGuiEXT::removeRenderLoop(const std::string& id)
|
||||||
{
|
{
|
||||||
const auto iter = _callPiplines.find(name);
|
auto fourccId = fourccValue(id);
|
||||||
if (iter != _callPiplines.end())
|
const auto iter = _renderPiplines.find(fourccId);
|
||||||
_callPiplines.erase(iter);
|
if (iter != _renderPiplines.end()) {
|
||||||
|
auto renderer = iter->second.renderer;
|
||||||
|
if (renderer->getParent())
|
||||||
|
renderer->removeFromParent();
|
||||||
|
renderer->release();
|
||||||
|
_renderPiplines.erase(iter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::tuple<ImVec2, ImVec2> getTextureUV(Sprite* sp)
|
static std::tuple<ImVec2, ImVec2> getTextureUV(Sprite* sp)
|
|
@ -10,18 +10,29 @@
|
||||||
|
|
||||||
NS_CC_EXT_BEGIN
|
NS_CC_EXT_BEGIN
|
||||||
|
|
||||||
class ImGuiLayer;
|
class ImGuiEXTRenderer;
|
||||||
class ImGuiEXT
|
class ImGuiEXT
|
||||||
{
|
{
|
||||||
friend class ImGuiLayer;
|
friend class ImGuiEXTRenderer;
|
||||||
void init();
|
void init();
|
||||||
public:
|
public:
|
||||||
static ImGuiEXT* getInstance();
|
static ImGuiEXT* getInstance();
|
||||||
static void destroyInstance();
|
static void destroyInstance();
|
||||||
static void setOnInit(const std::function<void(ImGuiEXT*)>& callBack);
|
static void setOnInit(const std::function<void(ImGuiEXT*)>& callBack);
|
||||||
|
|
||||||
void addCallback(const std::function<void()>& callBack, const std::string& name);
|
/// <summary>
|
||||||
void removeCallback(const std::string& name);
|
/// Add a ImGui render loop to specific scene
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">FOURCC starts with '#', such as "#abcd"</id>
|
||||||
|
/// <param name="scene">the scene to render ImGui</param>
|
||||||
|
/// <param name="onFrame">the ImGui render loop</param>
|
||||||
|
bool addRenderLoop(const std::string& id, Scene* scene, std::function<void()> onFrame);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove ImGui render loop
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">FOURCC starts with '#', such as "#abcd"</id>
|
||||||
|
void removeRenderLoop(const std::string& id);
|
||||||
|
|
||||||
// imgui helper
|
// imgui helper
|
||||||
void image(
|
void image(
|
||||||
|
@ -90,12 +101,18 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// perform draw ImGui stubs
|
// perform draw ImGui stubs
|
||||||
void onDraw();
|
void update();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::function<void(ImGuiEXT*)> _onInit;
|
static std::function<void(ImGuiEXT*)> _onInit;
|
||||||
|
|
||||||
std::unordered_map<std::string, std::function<void()>> _callPiplines;
|
struct RenderPipline {
|
||||||
|
ImGuiEXTRenderer* renderer;
|
||||||
|
std::function<void()> frame;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_map<uint32_t, RenderPipline> _renderPiplines;
|
||||||
|
|
||||||
std::unordered_map<Ref*, int> usedCCRefIdMap;
|
std::unordered_map<Ref*, int> usedCCRefIdMap;
|
||||||
// cocos objects should be retained until next frame
|
// cocos objects should be retained until next frame
|
||||||
Vector<Ref*> usedCCRef;
|
Vector<Ref*> usedCCRef;
|
|
@ -1,4 +1,4 @@
|
||||||
set(target_name ImGui)
|
set(target_name ImGuiEXT)
|
||||||
|
|
||||||
#~ if(WINDOWS)
|
#~ if(WINDOWS)
|
||||||
#~ include_directories(${COCOS2DX_ROOT_PATH}/external/win32-specific/gles/include/OGLES)
|
#~ include_directories(${COCOS2DX_ROOT_PATH}/external/win32-specific/gles/include/OGLES)
|
||||||
|
@ -7,7 +7,6 @@ include_directories(imgui)
|
||||||
|
|
||||||
set(HEADER
|
set(HEADER
|
||||||
CCImGuiEXT.h
|
CCImGuiEXT.h
|
||||||
CCImGuiLayer.h
|
|
||||||
# CCImGuiColorTextEdit.h
|
# CCImGuiColorTextEdit.h
|
||||||
imgui_impl_cocos2dx.h
|
imgui_impl_cocos2dx.h
|
||||||
imgui/imconfig.h
|
imgui/imconfig.h
|
||||||
|
@ -24,7 +23,6 @@ set(HEADER
|
||||||
|
|
||||||
set(SOURCE
|
set(SOURCE
|
||||||
CCImGuiEXT.cpp
|
CCImGuiEXT.cpp
|
||||||
CCImGuiLayer.cpp
|
|
||||||
# CCImGuiColorTextEdit.cpp
|
# CCImGuiColorTextEdit.cpp
|
||||||
imgui_impl_cocos2dx.cpp
|
imgui_impl_cocos2dx.cpp
|
||||||
imgui/imgui.cpp
|
imgui/imgui.cpp
|
|
@ -0,0 +1,37 @@
|
||||||
|
# ImGuiEXT of EGNX
|
||||||
|
Sync from https://github.com/Xrysnow/cocos2d-x-imgui and do a little changes
|
||||||
|
|
||||||
|
## Improvements
|
||||||
|
* Simple API, use add/remove renderLoop present ImGui GUI widgets
|
||||||
|
* Optimize call pipeline flow, support add/remove Node to Scene at ImGui render loop without container iterator damage
|
||||||
|
* Calculate deltaTime at ```ImGui_ImplCocos2dx_NewFrame``` to avoid error when ```cc.Director``` paused
|
||||||
|
* Refine ```Init/Shutdown```, Restore all callbacks for glfw to solve recreate ```ImGuiEXT``` instance support
|
||||||
|
* Use FOURCC for key of ImGui render loop
|
||||||
|
|
||||||
|
## How to use
|
||||||
|
1. Enable by cmake option -DBUILD_EXTENSION_IMGUIEXT=ON
|
||||||
|
2.
|
||||||
|
```cpp
|
||||||
|
#include "ImGuiEXT/CCImGuiEXT.h"
|
||||||
|
USING_NS_CC;
|
||||||
|
USING_NS_CC_EXT;
|
||||||
|
|
||||||
|
class GameScene : public Scene {
|
||||||
|
public:
|
||||||
|
void onEnter() override
|
||||||
|
{
|
||||||
|
ImGuiEXT::getInstance()->addRenderLoop("#im01", this, CC_CALLBACK_0(GameScene::onImGuiDraw, this));
|
||||||
|
}
|
||||||
|
void onExit() override
|
||||||
|
{
|
||||||
|
ImGuiEXT::getInstance()->removeRenderLoop("#im01");
|
||||||
|
}
|
||||||
|
void onImGuiDraw()
|
||||||
|
{
|
||||||
|
ImGui::Begin("window");
|
||||||
|
ImGui::Text("FPS=%.1f", 1.f / ImGui::GetIO().DeltaTime);
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
|
@ -45,6 +45,9 @@ static GLFWmousebuttonfun g_PrevUserCallbackMousebutton = nullptr;
|
||||||
static GLFWscrollfun g_PrevUserCallbackScroll = nullptr;
|
static GLFWscrollfun g_PrevUserCallbackScroll = nullptr;
|
||||||
static GLFWkeyfun g_PrevUserCallbackKey = nullptr;
|
static GLFWkeyfun g_PrevUserCallbackKey = nullptr;
|
||||||
static GLFWcharfun g_PrevUserCallbackChar = nullptr;
|
static GLFWcharfun g_PrevUserCallbackChar = nullptr;
|
||||||
|
|
||||||
|
static GLFWmonitorfun g_PrevUserCallbackMonitor = nullptr;
|
||||||
|
|
||||||
static bool g_WantUpdateMonitors = true;
|
static bool g_WantUpdateMonitors = true;
|
||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
|
@ -54,6 +57,11 @@ static void ImGui_ImplGlfw_UpdateMonitors();
|
||||||
|
|
||||||
#endif // CC_PLATFORM_PC
|
#endif // CC_PLATFORM_PC
|
||||||
|
|
||||||
|
// fps macro
|
||||||
|
#define CC_IMGUI_DEFAULT_DELTA (1 / 60.f)
|
||||||
|
#define CC_IMGUI_MIN_DELTA (1 / 1000.f)
|
||||||
|
#define CC_IMGUI_MAX_DELTA (1 / 30.f)
|
||||||
|
|
||||||
struct ProgramInfo
|
struct ProgramInfo
|
||||||
{
|
{
|
||||||
Program* program = nullptr;
|
Program* program = nullptr;
|
||||||
|
@ -487,7 +495,7 @@ static void ImGui_ImplOpenGL2_RenderWindow(ImGuiViewport* viewport, void*)
|
||||||
ImGui_ImplCocos2dx_RenderDrawData(viewport->DrawData);
|
ImGui_ImplCocos2dx_RenderDrawData(viewport->DrawData);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplCocos2dx_Init(bool install_callbacks)
|
bool ImGui_ImplCocos2dx_Init(bool install_callbacks /*TODO: need check whether callbacks installed at shutdown*/)
|
||||||
{
|
{
|
||||||
g_Time = 0.0;
|
g_Time = 0.0;
|
||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
|
@ -589,18 +597,21 @@ bool ImGui_ImplCocos2dx_Init(bool install_callbacks)
|
||||||
g_PrevUserCallbackChar = glfwSetCharCallback(window, ImGui_ImplCocos2dx_CharCallback);
|
g_PrevUserCallbackChar = glfwSetCharCallback(window, ImGui_ImplCocos2dx_CharCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update monitors the first time (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);
|
|
||||||
|
|
||||||
// Our mouse update function expect PlatformHandle to be filled for the main viewport
|
// Our mouse update function expect PlatformHandle to be filled for the main viewport
|
||||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||||
main_viewport->PlatformHandle = (void*)window;
|
main_viewport->PlatformHandle = (void*)window;
|
||||||
|
|
||||||
#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
|
#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
|
||||||
main_viewport->PlatformHandleRaw = glfwGetWin32Window(window);
|
main_viewport->PlatformHandleRaw = glfwGetWin32Window(window);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||||
ImGui_ImplGlfw_InitPlatformInterface();
|
ImGui_ImplGlfw_InitPlatformInterface();
|
||||||
|
else {
|
||||||
|
// Update monitors the first time (note: monitor callback are broken in GLFW 3.2 and earlier, see github.com/glfw/glfw/issues/784)
|
||||||
|
ImGui_ImplGlfw_UpdateMonitors();
|
||||||
|
g_PrevUserCallbackMonitor = glfwSetMonitorCallback(ImGui_ImplGlfw_MonitorCallback);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
/*
|
/*
|
||||||
auto e = cocos2d::EventListenerMouse::create();
|
auto e = cocos2d::EventListenerMouse::create();
|
||||||
|
@ -688,14 +699,38 @@ bool ImGui_ImplCocos2dx_Init(bool install_callbacks)
|
||||||
|
|
||||||
void ImGui_ImplCocos2dx_Shutdown()
|
void ImGui_ImplCocos2dx_Shutdown()
|
||||||
{
|
{
|
||||||
|
const auto window = ImGui_ImplCocos2dx_GetWindow();
|
||||||
|
|
||||||
ImGui::DestroyPlatformWindows();
|
ImGui::DestroyPlatformWindows();
|
||||||
|
|
||||||
#ifdef CC_PLATFORM_PC
|
#ifdef CC_PLATFORM_PC
|
||||||
|
glfwSetMonitorCallback(g_PrevUserCallbackMonitor);
|
||||||
|
g_PrevUserCallbackMonitor = nullptr;
|
||||||
|
|
||||||
|
// Restore mouse and char callback
|
||||||
|
glfwSetMouseButtonCallback(window, g_PrevUserCallbackMousebutton);
|
||||||
|
glfwSetScrollCallback(window, g_PrevUserCallbackScroll);
|
||||||
|
glfwSetKeyCallback(window, g_PrevUserCallbackKey);
|
||||||
|
glfwSetCharCallback(window, g_PrevUserCallbackChar);
|
||||||
|
g_PrevUserCallbackMousebutton = nullptr;
|
||||||
|
g_PrevUserCallbackScroll = nullptr;
|
||||||
|
g_PrevUserCallbackKey = nullptr;
|
||||||
|
g_PrevUserCallbackChar = nullptr;
|
||||||
|
|
||||||
|
// Restore monitor callback
|
||||||
|
if (g_PrevUserCallbackMonitor) {
|
||||||
|
glfwSetMonitorCallback(g_PrevUserCallbackMonitor);
|
||||||
|
g_PrevUserCallbackChar = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destroy cursors
|
||||||
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
|
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
|
||||||
{
|
{
|
||||||
glfwDestroyCursor(g_MouseCursors[cursor_n]);
|
glfwDestroyCursor(g_MouseCursors[cursor_n]);
|
||||||
g_MouseCursors[cursor_n] = nullptr;
|
g_MouseCursors[cursor_n] = nullptr;
|
||||||
}
|
}
|
||||||
#endif // CC_PLATFORM_PC
|
#endif // CC_PLATFORM_PC
|
||||||
|
|
||||||
ImGui_ImplCocos2dx_DestroyDeviceObjects();
|
ImGui_ImplCocos2dx_DestroyDeviceObjects();
|
||||||
ImGui::DestroyContext();
|
ImGui::DestroyContext();
|
||||||
}
|
}
|
||||||
|
@ -911,6 +946,14 @@ static void ImGui_ImplGlfw_UpdateMonitors()
|
||||||
|
|
||||||
void ImGui_ImplCocos2dx_NewFrame()
|
void ImGui_ImplCocos2dx_NewFrame()
|
||||||
{
|
{
|
||||||
|
static std::chrono::steady_clock::time_point s_lastFrameTime;
|
||||||
|
|
||||||
|
// Calculate deltaTime by self to avoid error when pause cocos2d::Director
|
||||||
|
auto now = std::chrono::steady_clock::now();
|
||||||
|
auto deltaTime = std::chrono::duration_cast<std::chrono::microseconds>(now - s_lastFrameTime).count() / 1000000.0f;
|
||||||
|
deltaTime = cocos2d::clampf(deltaTime, CC_IMGUI_MIN_DELTA, CC_IMGUI_MAX_DELTA);
|
||||||
|
s_lastFrameTime = now;
|
||||||
|
|
||||||
g_CallbackCommands.clear();
|
g_CallbackCommands.clear();
|
||||||
g_CustomCommands.clear();
|
g_CustomCommands.clear();
|
||||||
g_ProgramStates.clear();
|
g_ProgramStates.clear();
|
||||||
|
@ -945,7 +988,7 @@ void ImGui_ImplCocos2dx_NewFrame()
|
||||||
#endif // CC_PLATFORM_PC
|
#endif // CC_PLATFORM_PC
|
||||||
|
|
||||||
// Setup time step
|
// Setup time step
|
||||||
io.DeltaTime = Director::getInstance()->getDeltaTime();
|
io.DeltaTime = deltaTime;
|
||||||
|
|
||||||
ImGui_ImplCocos2dx_UpdateMousePosAndButtons();
|
ImGui_ImplCocos2dx_UpdateMousePosAndButtons();
|
||||||
ImGui_ImplCocos2dx_UpdateMouseCursor();
|
ImGui_ImplCocos2dx_UpdateMouseCursor();
|
||||||
|
@ -1307,7 +1350,7 @@ static void ImGui_ImplGlfw_InitPlatformInterface()
|
||||||
|
|
||||||
// Note: monitor callback are broken GLFW 3.2 and earlier (see github.com/glfw/glfw/issues/784)
|
// Note: monitor callback are broken GLFW 3.2 and earlier (see github.com/glfw/glfw/issues/784)
|
||||||
ImGui_ImplGlfw_UpdateMonitors();
|
ImGui_ImplGlfw_UpdateMonitors();
|
||||||
glfwSetMonitorCallback(ImGui_ImplGlfw_MonitorCallback);
|
g_PrevUserCallbackMonitor = glfwSetMonitorCallback(ImGui_ImplGlfw_MonitorCallback);
|
||||||
|
|
||||||
// Register main window handle (which is owned by the main application, not by us)
|
// Register main window handle (which is owned by the main application, not by us)
|
||||||
// This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same logic for main and secondary viewports.
|
// This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same logic for main and secondary viewports.
|
Loading…
Reference in New Issue