ocornut_imgui.cpp 16 KB

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