ocornut_imgui.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  1. /*
  2. * Copyright 2014-2015 Daniel Collin. All rights reserved.
  3. * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
  4. */
  5. #include <bgfx/bgfx.h>
  6. #include <bx/allocator.h>
  7. #include <bx/fpumath.h>
  8. #include <bx/timer.h>
  9. #include <ocornut-imgui/imgui.h>
  10. #include <ocornut-imgui/imgui_wm.h>
  11. #include "imgui.h"
  12. #include "ocornut_imgui.h"
  13. #include <stb/stb_image.c>
  14. #ifndef USE_ENTRY
  15. # if defined(SCI_NAMESPACE)
  16. # define USE_ENTRY 1
  17. # else
  18. # define USE_ENTRY 0
  19. # endif // defined(SCI_NAMESPACE)
  20. #endif // USE_ENTRY
  21. #if USE_ENTRY
  22. # include "../entry/entry.h"
  23. #endif // USE_ENTRY
  24. #if defined(SCI_NAMESPACE)
  25. # include "../entry/input.h"
  26. # include "scintilla.h"
  27. #endif // defined(SCI_NAMESPACE)
  28. #include "vs_ocornut_imgui.bin.h"
  29. #include "fs_ocornut_imgui.bin.h"
  30. class PlatformWindow : public ImGuiWM::PlatformWindow
  31. {
  32. typedef ImGuiWM::PlatformWindow Super;
  33. public:
  34. PlatformWindow(bool _mainWindow, bool _isDragWindow)
  35. : ImGuiWM::PlatformWindow(_mainWindow, _isDragWindow)
  36. , m_pos(0.0f, 0.0f)
  37. , m_size(0.0f, 0.0f)
  38. , m_drag(false)
  39. {
  40. #if USE_ENTRY
  41. if (!_mainWindow
  42. && !_isDragWindow)
  43. {
  44. m_window = entry::createWindow(0, 0, 640, 380);
  45. extern void pwToWindow(entry::WindowHandle _handle, class PlatformWindow* _pw);
  46. pwToWindow(m_window, this);
  47. }
  48. else
  49. {
  50. m_window.idx = 0;
  51. }
  52. #endif // USE_ENTRY
  53. }
  54. virtual ~PlatformWindow()
  55. {
  56. #if USE_ENTRY
  57. if (0 != m_window.idx)
  58. {
  59. entry::destroyWindow(m_window);
  60. }
  61. #endif // USE_ENTRY
  62. }
  63. virtual bool Init(ImGuiWM::PlatformWindow* /*_parent*/) BX_OVERRIDE
  64. {
  65. return true;
  66. }
  67. virtual const ImVec2& GetPosition() const BX_OVERRIDE
  68. {
  69. return m_pos;
  70. }
  71. virtual const ImVec2& GetSize() const BX_OVERRIDE
  72. {
  73. return m_size;
  74. }
  75. virtual void Show() BX_OVERRIDE
  76. {
  77. }
  78. virtual void Hide() BX_OVERRIDE
  79. {
  80. }
  81. virtual void SetSize(const ImVec2& _size) BX_OVERRIDE
  82. {
  83. #if USE_ENTRY
  84. if (0 != m_window.idx
  85. && m_size.x != _size.x
  86. && m_size.y != _size.y)
  87. {
  88. entry::setWindowSize(m_window, int32_t(_size.x), int32_t(_size.y) );
  89. }
  90. #endif // USE_ENTRY
  91. m_size = _size;
  92. }
  93. virtual void SetPosition(const ImVec2& _pos) BX_OVERRIDE
  94. {
  95. #if USE_ENTRY
  96. if (0 != m_window.idx
  97. && m_pos.x != _pos.x
  98. && m_pos.y != _pos.y)
  99. {
  100. entry::setWindowPos(m_window, int32_t(_pos.x), int32_t(_pos.y) );
  101. }
  102. #endif // USE_ENTRY
  103. m_pos = _pos;
  104. }
  105. virtual void SetTitle(const char* _title) BX_OVERRIDE
  106. {
  107. #if USE_ENTRY
  108. entry::setWindowTitle(m_window, _title);
  109. #else
  110. BX_UNUSED(_title);
  111. #endif // USE_ENTRY
  112. }
  113. virtual void PreUpdate() BX_OVERRIDE
  114. {
  115. }
  116. virtual void PaintBegin() BX_OVERRIDE;
  117. virtual void Paint() BX_OVERRIDE;
  118. virtual void PaintEnd() BX_OVERRIDE;
  119. virtual void Destroy() BX_OVERRIDE
  120. {
  121. }
  122. virtual void StartDrag() BX_OVERRIDE
  123. {
  124. m_drag = true;
  125. }
  126. virtual void StopDrag() BX_OVERRIDE
  127. {
  128. m_drag = false;
  129. }
  130. virtual bool IsDraging() BX_OVERRIDE
  131. {
  132. return m_drag;
  133. }
  134. private:
  135. ImVec2 m_pos;
  136. ImVec2 m_size;
  137. bool m_drag;
  138. #if USE_ENTRY
  139. entry::WindowHandle m_window;
  140. #endif // USE_ENTRY
  141. };
  142. class WindowManager : public ImGuiWM::WindowManager
  143. {
  144. typedef ImGuiWM::WindowManager Super;
  145. public:
  146. WindowManager()
  147. {
  148. }
  149. virtual ~WindowManager()
  150. {
  151. }
  152. protected:
  153. virtual ImGuiWM::PlatformWindow* CreatePlatformWindow(bool _main, ImGuiWM::PlatformWindow* _parent, bool _isDragWindow) BX_OVERRIDE
  154. {
  155. #if USE_ENTRY
  156. #else
  157. if (!_main
  158. && !_isDragWindow)
  159. {
  160. return NULL;
  161. }
  162. #endif // USE_ENTRY
  163. PlatformWindow* window = new (ImGui::MemAlloc(sizeof(PlatformWindow) ) ) PlatformWindow(_main, _isDragWindow);
  164. window->Init(_parent);
  165. return static_cast<ImGuiWM::PlatformWindow*>(window);
  166. }
  167. virtual void LogFormatted(const char* _str) BX_OVERRIDE
  168. {
  169. BX_TRACE("%s", _str); BX_UNUSED(_str);
  170. }
  171. virtual void InternalRun() BX_OVERRIDE
  172. {
  173. PreUpdate();
  174. Update();
  175. }
  176. };
  177. struct OcornutImguiContext
  178. {
  179. static void* memAlloc(size_t _size);
  180. static void memFree(void* _ptr);
  181. static void renderDrawLists(ImDrawData* _drawData);
  182. void render(ImDrawData* _drawData)
  183. {
  184. const ImGuiIO& io = ImGui::GetIO();
  185. const float width = io.DisplaySize.x;
  186. const float height = io.DisplaySize.y;
  187. {
  188. float ortho[16];
  189. bx::mtxOrtho(ortho, 0.0f, width, height, 0.0f, -1.0f, 1.0f);
  190. bgfx::setViewTransform(m_viewId, NULL, ortho);
  191. }
  192. #if USE_ENTRY
  193. for (uint32_t ii = 1; ii < BX_COUNTOF(m_window); ++ii)
  194. {
  195. Window& window = m_window[ii];
  196. if (bgfx::isValid(window.m_fbh) )
  197. {
  198. const uint8_t viewId = window.m_viewId;
  199. bgfx::setViewClear(viewId
  200. , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
  201. , 0x303030ff
  202. , 1.0f
  203. , 0
  204. );
  205. bgfx::setViewFrameBuffer(viewId, window.m_fbh);
  206. bgfx::setViewRect(viewId
  207. , 0
  208. , 0
  209. , window.m_state.m_width
  210. , window.m_state.m_height
  211. );
  212. float ortho[16];
  213. bx::mtxOrtho(ortho
  214. , 0.0f
  215. , float(window.m_state.m_width)
  216. , float(window.m_state.m_height)
  217. , 0.0f
  218. , -1.0f
  219. , 1.0f
  220. );
  221. bgfx::setViewTransform(viewId
  222. , NULL
  223. , ortho
  224. );
  225. }
  226. }
  227. #endif // USE_ENTRY
  228. // Render command lists
  229. for (int32_t ii = 0, num = _drawData->CmdListsCount; ii < num; ++ii)
  230. {
  231. bgfx::TransientVertexBuffer tvb;
  232. bgfx::TransientIndexBuffer tib;
  233. const ImDrawList* drawList = _drawData->CmdLists[ii];
  234. uint32_t numVertices = (uint32_t)drawList->VtxBuffer.size();
  235. uint32_t numIndices = (uint32_t)drawList->IdxBuffer.size();
  236. if (!bgfx::checkAvailTransientVertexBuffer(numVertices, m_decl)
  237. || !bgfx::checkAvailTransientIndexBuffer(numIndices) )
  238. {
  239. // not enough space in transient buffer just quit drawing the rest...
  240. break;
  241. }
  242. bgfx::allocTransientVertexBuffer(&tvb, numVertices, m_decl);
  243. bgfx::allocTransientIndexBuffer(&tib, numIndices);
  244. ImDrawVert* verts = (ImDrawVert*)tvb.data;
  245. memcpy(verts, drawList->VtxBuffer.begin(), numVertices * sizeof(ImDrawVert) );
  246. ImDrawIdx* indices = (ImDrawIdx*)tib.data;
  247. memcpy(indices, drawList->IdxBuffer.begin(), numIndices * sizeof(ImDrawIdx) );
  248. uint32_t offset = 0;
  249. for (const ImDrawCmd* cmd = drawList->CmdBuffer.begin(), *cmdEnd = drawList->CmdBuffer.end(); cmd != cmdEnd; ++cmd)
  250. {
  251. if (cmd->UserCallback)
  252. {
  253. cmd->UserCallback(drawList, cmd);
  254. }
  255. else if (0 != cmd->ElemCount)
  256. {
  257. uint64_t state = 0
  258. | BGFX_STATE_RGB_WRITE
  259. | BGFX_STATE_ALPHA_WRITE
  260. | BGFX_STATE_MSAA
  261. ;
  262. bgfx::TextureHandle th = m_texture;
  263. if (NULL != cmd->TextureId)
  264. {
  265. union { ImTextureID ptr; struct { uint16_t flags; bgfx::TextureHandle handle; } s; } texture = { cmd->TextureId };
  266. state |= 0 != (IMGUI_FLAGS_ALPHA_BLEND & texture.s.flags)
  267. ? BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA)
  268. : BGFX_STATE_NONE
  269. ;
  270. th = texture.s.handle;
  271. }
  272. else
  273. {
  274. state |= BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA);
  275. }
  276. const uint16_t xx = uint16_t(bx::fmax(cmd->ClipRect.x, 0.0f) );
  277. const uint16_t yy = uint16_t(bx::fmax(cmd->ClipRect.y, 0.0f) );
  278. bgfx::setScissor(xx, yy
  279. , uint16_t(bx::fmin(cmd->ClipRect.z, 65535.0f)-xx)
  280. , uint16_t(bx::fmin(cmd->ClipRect.w, 65535.0f)-yy)
  281. );
  282. bgfx::setState(state);
  283. bgfx::setTexture(0, s_tex, th);
  284. bgfx::setVertexBuffer(&tvb, 0, numVertices);
  285. bgfx::setIndexBuffer(&tib, offset, cmd->ElemCount);
  286. bgfx::submit(cmd->ViewId, m_program);
  287. }
  288. offset += cmd->ElemCount;
  289. }
  290. }
  291. }
  292. void create(const void* _data, uint32_t _size, float _fontSize, bx::AllocatorI* _allocator)
  293. {
  294. m_viewId = 255;
  295. m_allocator = _allocator;
  296. m_lastScroll = 0;
  297. m_last = bx::getHPCounter();
  298. ImGuiIO& io = ImGui::GetIO();
  299. io.RenderDrawListsFn = renderDrawLists;
  300. if (NULL != m_allocator)
  301. {
  302. io.MemAllocFn = memAlloc;
  303. io.MemFreeFn = memFree;
  304. }
  305. io.DisplaySize = ImVec2(1280.0f, 720.0f);
  306. io.DeltaTime = 1.0f / 60.0f;
  307. io.IniFilename = NULL;
  308. #if defined(SCI_NAMESPACE)
  309. io.KeyMap[ImGuiKey_Tab] = (int)entry::Key::Tab;
  310. io.KeyMap[ImGuiKey_LeftArrow] = (int)entry::Key::Left;
  311. io.KeyMap[ImGuiKey_RightArrow] = (int)entry::Key::Right;
  312. io.KeyMap[ImGuiKey_UpArrow] = (int)entry::Key::Up;
  313. io.KeyMap[ImGuiKey_DownArrow] = (int)entry::Key::Down;
  314. io.KeyMap[ImGuiKey_Home] = (int)entry::Key::Home;
  315. io.KeyMap[ImGuiKey_End] = (int)entry::Key::End;
  316. io.KeyMap[ImGuiKey_Delete] = (int)entry::Key::Delete;
  317. io.KeyMap[ImGuiKey_Backspace] = (int)entry::Key::Backspace;
  318. io.KeyMap[ImGuiKey_Enter] = (int)entry::Key::Return;
  319. io.KeyMap[ImGuiKey_Escape] = (int)entry::Key::Esc;
  320. io.KeyMap[ImGuiKey_A] = (int)entry::Key::KeyA;
  321. io.KeyMap[ImGuiKey_C] = (int)entry::Key::KeyC;
  322. io.KeyMap[ImGuiKey_V] = (int)entry::Key::KeyV;
  323. io.KeyMap[ImGuiKey_X] = (int)entry::Key::KeyX;
  324. io.KeyMap[ImGuiKey_Y] = (int)entry::Key::KeyY;
  325. io.KeyMap[ImGuiKey_Z] = (int)entry::Key::KeyZ;
  326. #endif // defined(SCI_NAMESPACE)
  327. const bgfx::Memory* vsmem;
  328. const bgfx::Memory* fsmem;
  329. switch (bgfx::getRendererType() )
  330. {
  331. case bgfx::RendererType::Direct3D9:
  332. vsmem = bgfx::makeRef(vs_ocornut_imgui_dx9, sizeof(vs_ocornut_imgui_dx9) );
  333. fsmem = bgfx::makeRef(fs_ocornut_imgui_dx9, sizeof(fs_ocornut_imgui_dx9) );
  334. break;
  335. case bgfx::RendererType::Direct3D11:
  336. case bgfx::RendererType::Direct3D12:
  337. vsmem = bgfx::makeRef(vs_ocornut_imgui_dx11, sizeof(vs_ocornut_imgui_dx11) );
  338. fsmem = bgfx::makeRef(fs_ocornut_imgui_dx11, sizeof(fs_ocornut_imgui_dx11) );
  339. break;
  340. case bgfx::RendererType::Metal:
  341. vsmem = bgfx::makeRef(vs_ocornut_imgui_mtl, sizeof(vs_ocornut_imgui_mtl) );
  342. fsmem = bgfx::makeRef(fs_ocornut_imgui_mtl, sizeof(fs_ocornut_imgui_mtl) );
  343. break;
  344. default:
  345. vsmem = bgfx::makeRef(vs_ocornut_imgui_glsl, sizeof(vs_ocornut_imgui_glsl) );
  346. fsmem = bgfx::makeRef(fs_ocornut_imgui_glsl, sizeof(fs_ocornut_imgui_glsl) );
  347. break;
  348. }
  349. bgfx::ShaderHandle vsh = bgfx::createShader(vsmem);
  350. bgfx::ShaderHandle fsh = bgfx::createShader(fsmem);
  351. m_program = bgfx::createProgram(vsh, fsh, true);
  352. m_decl
  353. .begin()
  354. .add(bgfx::Attrib::Position, 2, bgfx::AttribType::Float)
  355. .add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
  356. .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
  357. .end();
  358. s_tex = bgfx::createUniform("s_tex", bgfx::UniformType::Int1);
  359. uint8_t* data;
  360. int32_t width;
  361. int32_t height;
  362. {
  363. void* font = ImGui::MemAlloc(_size);
  364. memcpy(font, _data, _size);
  365. io.Fonts->AddFontFromMemoryTTF(font, _size, _fontSize);
  366. }
  367. io.Fonts->GetTexDataAsRGBA32(&data, &width, &height);
  368. m_texture = bgfx::createTexture2D( (uint16_t)width
  369. , (uint16_t)height
  370. , 1
  371. , bgfx::TextureFormat::BGRA8
  372. , 0
  373. , bgfx::copy(data, width*height*4)
  374. );
  375. ImGuiStyle& style = ImGui::GetStyle();
  376. style.FrameRounding = 4.0f;
  377. m_wm = BX_NEW(m_allocator, WindowManager);
  378. m_wm->Init();
  379. #if 0
  380. {
  381. class Window : public ImGuiWM::Window
  382. {
  383. public:
  384. Window(const char* _title)
  385. : ImGuiWM::Window()
  386. {
  387. SetTitle(_title);
  388. }
  389. virtual void OnGui() BX_OVERRIDE
  390. {
  391. }
  392. };
  393. class WindowX : public ImGuiWM::Window
  394. {
  395. public:
  396. WindowX(const char* _title)
  397. : ImGuiWM::Window()
  398. {
  399. SetTitle(_title);
  400. }
  401. virtual void OnGui() BX_OVERRIDE
  402. {
  403. #if defined(SCI_NAMESPACE) && 0
  404. bool opened = true;
  405. ImGuiScintilla("Scintilla Editor", &opened, ImVec2(640.0f, 480.0f) );
  406. #endif // 0
  407. }
  408. };
  409. Window* w0 = new Window("test");
  410. WindowX* w1 = new WindowX("Scintilla");
  411. Window* w2 = new Window("xyzw");
  412. Window* w3 = new Window("0123");
  413. m_wm->Dock(w0);
  414. m_wm->DockWith(w1, w0, ImGuiWM::E_DOCK_ORIENTATION_RIGHT);
  415. m_wm->DockWith(w2, w1, ImGuiWM::E_DOCK_ORIENTATION_BOTTOM);
  416. m_wm->DockWith(w3, w0, ImGuiWM::E_DOCK_ORIENTATION_BOTTOM);
  417. }
  418. #endif // 0
  419. }
  420. void destroy()
  421. {
  422. m_wm->Exit();
  423. BX_DELETE(m_allocator, m_wm);
  424. ImGui::Shutdown();
  425. bgfx::destroyUniform(s_tex);
  426. bgfx::destroyTexture(m_texture);
  427. bgfx::destroyProgram(m_program);
  428. m_allocator = NULL;
  429. }
  430. void beginFrame(int32_t _mx, int32_t _my, uint8_t _button, int32_t _scroll, int _width, int _height, char _inputChar, uint8_t _viewId)
  431. {
  432. m_viewId = _viewId;
  433. ImGuiIO& io = ImGui::GetIO();
  434. if (_inputChar < 0x7f)
  435. {
  436. io.AddInputCharacter(_inputChar); // ASCII or GTFO! :(
  437. }
  438. io.DisplaySize = ImVec2( (float)_width, (float)_height);
  439. const int64_t now = bx::getHPCounter();
  440. const int64_t frameTime = now - m_last;
  441. m_last = now;
  442. const double freq = double(bx::getHPFrequency() );
  443. io.DeltaTime = float(frameTime/freq);
  444. io.MousePos = ImVec2( (float)_mx, (float)_my);
  445. io.MouseDown[0] = 0 != (_button & IMGUI_MBUT_LEFT);
  446. io.MouseDown[1] = 0 != (_button & IMGUI_MBUT_RIGHT);
  447. io.MouseDown[2] = 0 != (_button & IMGUI_MBUT_MIDDLE);
  448. io.MouseWheel = (float)(_scroll - m_lastScroll);
  449. m_lastScroll = _scroll;
  450. #if defined(SCI_NAMESPACE)
  451. uint8_t modifiers = inputGetModifiersState();
  452. io.KeyShift = 0 != (modifiers & (entry::Modifier::LeftShift | entry::Modifier::RightShift) );
  453. io.KeyCtrl = 0 != (modifiers & (entry::Modifier::LeftCtrl | entry::Modifier::RightCtrl ) );
  454. io.KeyAlt = 0 != (modifiers & (entry::Modifier::LeftAlt | entry::Modifier::RightAlt ) );
  455. for (int32_t ii = 0; ii < (int32_t)entry::Key::Count; ++ii)
  456. {
  457. io.KeysDown[ii] = inputGetKeyState(entry::Key::Enum(ii) );
  458. }
  459. #endif // defined(SCI_NAMESPACE)
  460. ImGui::NewFrame();
  461. ImGui::PushStyleVar(ImGuiStyleVar_ViewId, (float)_viewId);
  462. #if 0
  463. ImGui::ShowTestWindow(); //Debug only.
  464. #endif // 0
  465. #if 0
  466. extern void ShowExampleAppCustomNodeGraph(bool* opened);
  467. bool opened = true;
  468. ShowExampleAppCustomNodeGraph(&opened);
  469. #endif // 0
  470. }
  471. void endFrame()
  472. {
  473. m_wm->Run();
  474. ImGui::PopStyleVar(1);
  475. ImGui::Render();
  476. }
  477. bx::AllocatorI* m_allocator;
  478. bgfx::VertexDecl m_decl;
  479. bgfx::ProgramHandle m_program;
  480. bgfx::TextureHandle m_texture;
  481. bgfx::UniformHandle s_tex;
  482. WindowManager* m_wm;
  483. int64_t m_last;
  484. int32_t m_lastScroll;
  485. uint8_t m_viewId;
  486. #if USE_ENTRY
  487. struct Window
  488. {
  489. Window()
  490. {
  491. m_fbh.idx = bgfx::invalidHandle;
  492. }
  493. entry::WindowState m_state;
  494. PlatformWindow* m_pw;
  495. bgfx::FrameBufferHandle m_fbh;
  496. uint8_t m_viewId;
  497. };
  498. Window m_window[16];
  499. #endif // USE_ENTRY
  500. };
  501. static OcornutImguiContext s_ctx;
  502. void PlatformWindow::PaintBegin()
  503. {
  504. #if USE_ENTRY
  505. if (!m_bIsDragWindow)
  506. {
  507. OcornutImguiContext::Window& win = s_ctx.m_window[m_window.idx];
  508. entry::WindowState& state = win.m_state;
  509. ImGuiIO& io = ImGui::GetIO();
  510. io.MousePos = ImVec2((float)state.m_mouse.m_mx, (float)state.m_mouse.m_my);
  511. io.MouseDown[0] = !!state.m_mouse.m_buttons[entry::MouseButton::Left];
  512. io.MouseDown[1] = !!state.m_mouse.m_buttons[entry::MouseButton::Right];
  513. io.MouseDown[2] = !!state.m_mouse.m_buttons[entry::MouseButton::Middle];
  514. io.MouseWheel = float(state.m_mouse.m_mz);
  515. ImGui::PushStyleVar(ImGuiStyleVar_ViewId, (float)win.m_viewId);
  516. }
  517. #endif // USE_ENTRY
  518. }
  519. void PlatformWindow::Paint()
  520. {
  521. if (!m_bIsDragWindow)
  522. {
  523. Super::Paint();
  524. }
  525. }
  526. void PlatformWindow::PaintEnd()
  527. {
  528. #if USE_ENTRY
  529. if (!m_bIsDragWindow)
  530. {
  531. ImGui::PopStyleVar(1);
  532. entry::WindowState& state = s_ctx.m_window[0].m_state;
  533. ImGuiIO& io = ImGui::GetIO();
  534. io.MousePos = ImVec2((float)state.m_mouse.m_mx, (float)state.m_mouse.m_my);
  535. io.MouseDown[0] = !!state.m_mouse.m_buttons[entry::MouseButton::Left];
  536. io.MouseDown[1] = !!state.m_mouse.m_buttons[entry::MouseButton::Right];
  537. io.MouseDown[2] = !!state.m_mouse.m_buttons[entry::MouseButton::Middle];
  538. io.MouseWheel = float(state.m_mouse.m_mz);
  539. }
  540. #endif // USE_ENTRY
  541. }
  542. #if USE_ENTRY
  543. void pwToWindow(entry::WindowHandle _handle, PlatformWindow* _pw)
  544. {
  545. s_ctx.m_window[_handle.idx].m_pw = _pw;
  546. }
  547. void imguiUpdateWindow(const entry::WindowState& _state)
  548. {
  549. OcornutImguiContext::Window& window = s_ctx.m_window[_state.m_handle.idx];
  550. if (window.m_state.m_nwh != _state.m_nwh
  551. || (window.m_state.m_width != _state.m_width
  552. || window.m_state.m_height != _state.m_height) )
  553. {
  554. // When window changes size or native window handle changed
  555. // frame buffer must be recreated.
  556. if (bgfx::isValid(window.m_fbh) )
  557. {
  558. bgfx::destroyFrameBuffer(window.m_fbh);
  559. window.m_fbh.idx = bgfx::invalidHandle;
  560. }
  561. if (NULL != _state.m_nwh)
  562. {
  563. window.m_fbh = bgfx::createFrameBuffer(_state.m_nwh, _state.m_width, _state.m_height);
  564. window.m_viewId = 200 + _state.m_handle.idx;
  565. }
  566. else
  567. {
  568. window.m_viewId = s_ctx.m_viewId;
  569. }
  570. }
  571. memcpy(&window.m_state, &_state, sizeof(entry::WindowState) );
  572. }
  573. #endif // USE_ENTRY
  574. void* OcornutImguiContext::memAlloc(size_t _size)
  575. {
  576. return BX_ALLOC(s_ctx.m_allocator, _size);
  577. }
  578. void OcornutImguiContext::memFree(void* _ptr)
  579. {
  580. BX_FREE(s_ctx.m_allocator, _ptr);
  581. }
  582. void OcornutImguiContext::renderDrawLists(ImDrawData* _drawData)
  583. {
  584. s_ctx.render(_drawData);
  585. }
  586. void IMGUI_create(const void* _data, uint32_t _size, float _fontSize, bx::AllocatorI* _allocator)
  587. {
  588. s_ctx.create(_data, _size, _fontSize, _allocator);
  589. }
  590. void IMGUI_destroy()
  591. {
  592. s_ctx.destroy();
  593. }
  594. void IMGUI_beginFrame(int32_t _mx, int32_t _my, uint8_t _button, int32_t _scroll, int _width, int _height, char _inputChar, uint8_t _viewId)
  595. {
  596. s_ctx.beginFrame(_mx, _my, _button, _scroll, _width, _height, _inputChar, _viewId);
  597. }
  598. void IMGUI_endFrame()
  599. {
  600. s_ctx.endFrame();
  601. }