From a2d845f9dda5f591f57d79158db1c7548c4ce2e9 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 12 Oct 2020 18:57:04 +0200 Subject: [PATCH] Moving backends code from examples/ to backends/ (step 4: update documentation, much improvement) --- backends/README.txt | 154 ++++++++++++++++++++++++++++ docs/CHANGELOG.txt | 1 + examples/README.txt | 243 ++++++++++++++++++-------------------------- 3 files changed, 252 insertions(+), 146 deletions(-) create mode 100644 backends/README.txt diff --git a/backends/README.txt b/backends/README.txt new file mode 100644 index 00000000..9dd9dfcf --- /dev/null +++ b/backends/README.txt @@ -0,0 +1,154 @@ +----------------------------------------------------------------------- + dear imgui, v1.80 WIP + Backends +----------------------------------------------------------------------- + (See docs/ and examples/ for more documentation) +----------------------------------------------------------------------- + +This folder contains backends for popular platforms/graphics API, which you can use in +your application or engine to easily integrate Dear ImGui. + +- The 'Platform' backends are in charge of: mouse/keyboard/gamepad inputs, cursor shape, timing, windowing. + e.g. Windows (imgui_impl_win32.cpp), GLFW (imgui_impl_glfw.cpp), SDL2 (imgui_impl_sdl.cpp), etc. + +- The 'Renderer' backends are in charge of: creating atlas texture, rendering imgui draw data. + e.g. DirectX11 (imgui_impl_dx11.cpp), OpenGL/WebGL (imgui_impl_opengl3.cpp), Vulkan (imgui_impl_vulkan.cpp), etc. + +- For some high-level frameworks, a single backend usually handle both 'Platform' and 'Renderer' parts. + e.g. Allegro 5 (imgui_impl_allegro5.cpp), Marmalade (imgui_impl_marmalade5.cpp). + +An application usually combines 1 Platform backend + 1 Renderer backend + main ImGui sources. +For example, the example_win32_directx11/ application combines imgui_impl_win32.cpp + imgui_impl_dx11.cpp. +See examples/README.txt for details. + + +--------------------------------------- + WHAT ARE BACKENDS? +--------------------------------------- + +Dear ImGui is highly portable and only requires a few things to run and render, typically: + + - Required: providing mouse/keyboard inputs. + - Required: uploading the font atlas texture into graphics memory. + - Required: rendering indexed textured triangles with a clipping rectangle. + + Extra features are opt-in, our backends try to support as many as possible: + + - Optional: custom texture binding support. + - Optional: clipboard support. + - Optional: gamepad support. + - Optional: mouse cursor shape support. + - Optional: IME support. + - Optional: multi-viewports support. + etc. + +This is essentially what the backends in this folder are providing + obligatory portability cruft. + +It is important to understand the difference between the core Dear ImGui library (files in the root folder) +and backends which we are describing here (backends/ folder). + +- Some issues may only be backend or platform specific. +- You should be able to write backends for pretty much any platform and any 3D graphics API. + e.g. get creative and have your backend perform rendering remotely, on a different machine + than the one running Dear ImGui, etc. + + +----------------------------------------------------------------------- + USING A CUSTOM ENGINE? +----------------------------------------------------------------------- + +You will likely be tempted to start by rewrite your own backend using your own custom/high-level facilities... +Think twice! + +If you are new to Dear ImGui, first try using the existing backends as-is. +You will save lots of time integrating the library. +You can LATER decide to rewrite yourself a custom backend if you really need to. +In most situations, custom backends have less features and more bugs than the standard backends we provide. +If you want portability, you can use multiple backends and choose between them either at compile time +or at runtime. + +Example A: your engine is built over Windows + DirectX11 but you have your own high-level rendering +system layered over DirectX11. + - Suggestion: try using imgui_impl_win32.cpp + imgui_impl_dx11.cpp first. + Once it works, if you really need it you can replace the imgui_impl_dx11.cpp code with a + custom renderer using your own rendering functions, and keep using the standard Win32 code etc. + +Example B: your engine runs on Windows, Mac, Linux and uses DirectX11, Metal, Vulkan respectively. + - Suggestion: use multiple generic backends! + Once it works, if you really need it you can replace parts of backends with your own abstractions. + +Example C: your engine runs on platforms we can't provide public backends for (e.g. PS4/PS5, Switch), +and you have high-level systems everywhere. + - Suggestion: try using a non-portable backend first (e.g. win32 + underlying graphics API) to get + your desktop builds working first. This will get you running faster and get your acquainted with + how Dear ImGui works and is setup. You can then rewrite a custom backend using your own engine API. + +Also: +The multi-viewports feature of the 'docking' branch allows Dear ImGui windows to be seamlessly detached +from the main application window. This is achieved using an extra layer to the Platform and Renderer +backends, which allows Dear ImGui to communicate platform-specific requests. +Supporting the multi-viewports feature correctly using 100% of your own abstractions is more difficult +than supporting single-viewport. +If you decide to use unmodified imgui_impl_xxxx.cpp files, you can automatically benefit from +improvements and fixes related to viewports and platform windows without extra work on your side. + + +--------------------------------------- + LIST OF BACKENDS +--------------------------------------- + +List of Platforms Backends in this repository: + + imgui_impl_glfw.cpp ; GLFW (Windows, macOS, Linux, etc.) http://www.glfw.org/ + imgui_impl_osx.mm ; macOS native API (not as feature complete as glfw/sdl backends) + imgui_impl_sdl.cpp ; SDL2 (Windows, macOS, Linux, iOS, Android) https://www.libsdl.org + imgui_impl_win32.cpp ; Win32 native API (Windows) + imgui_impl_glut.cpp ; GLUT/FreeGLUT (absolutely not recommended in 2020!) + +List of Renderer Backends in this repository: + + imgui_impl_dx9.cpp ; DirectX9 + imgui_impl_dx10.cpp ; DirectX10 + imgui_impl_dx11.cpp ; DirectX11 + imgui_impl_dx12.cpp ; DirectX12 + imgui_impl_metal.mm ; Metal (with ObjC) + imgui_impl_opengl2.cpp ; OpenGL 2 (legacy, fixed pipeline <- don't use with modern OpenGL context) + imgui_impl_opengl3.cpp ; OpenGL 3/4, OpenGL ES 2, OpenGL ES 3 (modern programmable pipeline) + imgui_impl_vulkan.cpp ; Vulkan + +Emscripten is also supported. +The example_emscripten/ app uses imgui_impl_sdl.cpp + imgui_impl_opengl3.cpp, but other combos are possible. + +List of high-level Frameworks Backends in this repository: (combine Platform + Renderer) + + imgui_impl_allegro5.cpp + imgui_impl_marmalade.cpp + +Backends for third-party frameworks, graphics API or other programming languages: + + https://github.com/ocornut/imgui/wiki/Bindings + + (AGS/Adventure Game Studio, Amethyst, bsf, Cinder, Cocos2d-x, Diligent Engine, Flexium, + GML/Game Maker Studio2, GTK3+OpenGL3, Irrlicht Engine, LÖVE+LUA, Magnum, NanoRT, Nim Game Lib, + Ogre, openFrameworks, OSG/OpenSceneGraph, Orx, px_render, Qt/QtDirect3D, SFML, Sokol, + Unreal Engine 4, vtk, Win32 GDI, etc.) + + +--------------------------------------- + RECOMMENDED BACKENDS +--------------------------------------- + +Recommended platform/frameworks for portable applications: + + Library: GLFW + Webpage: https://github.com/glfw/glfw + Backend: imgui_impl_glfw.cpp + + Library: SDL2 + Webpage: https://www.libsdl.org + Backend: imgui_impl_sdl.cpp + + Library: Sokol (lower-level than GLFW/SDL) + Webpage: https://github.com/floooh/sokol + Backend: Use util/sokol_imgui.h in Sokol repository. + diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 9af626e4..a01917de 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -53,6 +53,7 @@ Breaking Changes: Other Changes: +- Docs: Split Backends and Examples README and improved them. - Docs: Consistently renamed all occurences of "binding" and "back-end" to "backend" in comments and docs. diff --git a/examples/README.txt b/examples/README.txt index 71700d8f..45f0ae66 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -1,33 +1,14 @@ ----------------------------------------------------------------------- dear imgui, v1.80 WIP + Examples applications ----------------------------------------------------------------------- - examples/README.txt - (This is the README file for the examples/ folder. See docs/ for more documentation) + (See docs/ and backends/ for more documentation) ----------------------------------------------------------------------- -Dear ImGui is highly portable and only requires a few things to run and render: +This folder contains example applications (standalone, ready-to-build) for variety of +platforms and graphics APIs. They all use standard backends from the backends/ folder. - - Providing mouse/keyboard inputs - - Uploading the font atlas texture into graphics memory - - Providing a render function to render indexed textured triangles - - Optional: clipboard support, mouse cursor supports, Windows IME support, etc. - -This is essentially what the example backends in this folder are providing + obligatory portability cruft. - -It is important to understand the difference between the core Dear ImGui library (files in the root folder) -and examples backends which we are describing here (examples/ folder). -You should be able to write backends for pretty much any platform and any 3D graphics API. With some extra -effort you can even perform the rendering remotely, on a different machine than the one running the logic. - -This folder contains two things: - - - Example backends for popular platforms/graphics API, which you can use as is or adapt for your own use. - They are the imgui_impl_XXXX files found in the examples/ folder. - - - Example applications (standalone, ready-to-build) using the aforementioned backends. - They are the in the XXXX_example/ sub-folders. - -You can find binaries of some of those example applications at: +You can find Windows binaries for some of those example applications at: http://www.dearimgui.org/binaries @@ -35,144 +16,72 @@ You can find binaries of some of those example applications at: GETTING STARTED --------------------------------------- - - Please read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup Dear ImGui in your codebase. - Please read the comments and instruction at the top of each file. - Please read FAQ at http://www.dearimgui.org/faq +Integration in a typical existing application, should take <20 lines when using standard backends. - - If you are using of the backend provided here, you can add the imgui_impl_xxx.cpp/h files - to your project and use them unmodified. Each imgui_impl_xxxx.cpp comes with its own individual - Changelog at the top of the .cpp files, so if you want to update them later it will be easier to - catch up with what changed. + At initialization: + call ImGui::CreateContext() + call ImGui_ImplXXXX_Init() for each backend. - - Dear ImGui has no particular extra lag for most behaviors, e.g. the value of 'io.MousePos' provided in - NewFrame() will result at the time of EndFrame()/Render() in a moved windows rendered following that mouse - movement. At 60 FPS your experience should be pleasant. - However, consider that OS mouse cursors are typically drawn through a very specific hardware accelerated - path and will feel smoother than the majority of contents rendererd via regular graphics API (including, - but not limited to Dear ImGui windows). Because UI rendering and interaction happens on the same plane as - the mouse, that disconnect may be jarring to particularly sensitive users. - You may experiment with enabling the io.MouseDrawCursor flag to request Dear ImGui to draw a mouse cursor - using the regular graphics API, to help you visualize the difference between a "hardware" cursor and a - regularly rendered software cursor. - However, rendering a mouse cursor at 60 FPS will feel sluggish so you likely won't want to enable that at - all times. It might be beneficial for the user experience to switch to a software rendered cursor _only_ - when an interactive drag is in progress. - Note that some setup or GPU drivers are likely to be causing extra display lag depending on their settings. - If you feel that dragging windows feels laggy and you are not sure what the cause is: try to build a simple - drawing a flat 2D shape directly under the mouse cursor. + At the beginning of your frame: + call ImGui_ImplXXXX_NewFrame() for each backend. + call ImGui::NewFrame() + At the end of your frame: + call ImGui::Render() + call ImGui_ImplXXXX_RenderDrawData() for your Renderer backend. ---------------------------------------- - EXAMPLE BACKENDS ---------------------------------------- + At shutdown: + call ImGui_ImplXXXX_Shutdown() for each backend. + call ImGui::DestroyContext() -Most the example backends are split in 2 parts: +Example (using backends/imgui_impl_win32.cpp + backends/imgui_impl_dx11.cpp): - - The "Platform" backends, in charge of: mouse/keyboard/gamepad inputs, cursor shape, timing, windowing. - Examples: Windows (imgui_impl_win32.cpp), GLFW (imgui_impl_glfw.cpp), SDL2 (imgui_impl_sdl.cpp), etc. + // Create a Dear ImGui context, setup some options + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable some options + + // Initialize Platform + Renderer backends (here: using imgui_impl_win32.cpp + imgui_impl_dx11.cpp) + ImGui_ImplWin32_Init(my_hwnd); + ImGui_ImplDX11_Init(my_d3d_device, my_d3d_device_context); + + // Application main loop + while (true) + { + // Beginning of frame: update Renderer + Platform backend, start Dear ImGui frame + ImGui_ImplDX11_NewFrame(); + ImGui_ImplWin32_NewFrame(); + ImGui::NewFrame(); + + // Any application code here + ImGui::Text("Hello, world!"); + + // End of frame: render Dear ImGui + ImGui::Render(); + ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); - - The "Renderer" backends, in charge of: creating the main font texture, rendering imgui draw data. - Examples: DirectX11 (imgui_impl_dx11.cpp), GL3 (imgui_impl_opengl3.cpp), Vulkan (imgui_impl_vulkan.cpp), etc. + // Swap + g_pSwapChain->Present(1, 0); + } - - The example _applications_ usually combine 1 platform + 1 renderer backend to create a working program. - Examples: the example_win32_directx11/ application combines imgui_impl_win32.cpp + imgui_impl_dx11.cpp. + // Shutdown + ImGui_ImplDX11_Shutdown(); + ImGui_ImplWin32_Shutdown(); + ImGui::DestroyContext(); - - Some backends for higher level frameworks carry both "Platform" and "Renderer" parts in one file. - This is the case for Allegro 5 (imgui_impl_allegro5.cpp), Marmalade (imgui_impl_marmalade5.cpp). +Please read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup Dear ImGui in your codebase. +Please read the comments and instruction at the top of each file. +Please read FAQ at http://www.dearimgui.org/faq - - If you use your own engine, you may decide to use some of existing backends and/or rewrite some using - your own API. As a recommendation, if you are new to Dear ImGui, try using the existing backend as-is - first, before moving on to rewrite some of the code. Although it is tempting to rewrite both of the - imgui_impl_xxxx files to fit under your coding style, consider that it is not necessary! - In fact, if you are new to Dear ImGui, rewriting them will almost always be harder. - - Example: your engine is built over Windows + DirectX11 but you have your own high-level rendering - system layered over DirectX11. - Suggestion: step 1: try using imgui_impl_win32.cpp + imgui_impl_dx11.cpp first. - Once this work, _if_ you want you can replace the imgui_impl_dx11.cpp code with a custom renderer - using your own functions, etc. - Please consider using the backends to the lower-level platform/graphics API as-is. - - Example: your engine is multi-platform (consoles, phones, etc.), you have high-level systems everywhere. - Suggestion: step 1: try using a non-portable backend first (e.g. win32 + underlying graphics API)! - This is counter-intuitive, but this will get you running faster! Once you better understand how imgui - works and is bound, you can rewrite the code using your own systems. - - - Road-map: Dear ImGui 1.80 (WIP currently in the "docking" branch) will allows imgui windows to be - seamlessly detached from the main application window. This is achieved using an extra layer to the - platform and renderer backends, which allows Dear ImGui to communicate platform-specific requests. - If you decide to use unmodified imgui_impl_xxxx.cpp files, you will automatically benefit from - improvements and fixes related to viewports and platform windows without extra work on your side. - - -List of Platforms Backends in this repository: - - imgui_impl_glfw.cpp ; GLFW (Windows, macOS, Linux, etc.) http://www.glfw.org/ - imgui_impl_osx.mm ; macOS native API (not as feature complete as glfw/sdl backends) - imgui_impl_sdl.cpp ; SDL2 (Windows, macOS, Linux, iOS, Android) https://www.libsdl.org - imgui_impl_win32.cpp ; Win32 native API (Windows) - imgui_impl_glut.cpp ; GLUT/FreeGLUT (absolutely not recommended in 2020!) - -List of Renderer Backends in this repository: - - imgui_impl_dx9.cpp ; DirectX9 - imgui_impl_dx10.cpp ; DirectX10 - imgui_impl_dx11.cpp ; DirectX11 - imgui_impl_dx12.cpp ; DirectX12 - imgui_impl_metal.mm ; Metal (with ObjC) - imgui_impl_opengl2.cpp ; OpenGL 2 (legacy, fixed pipeline <- don't use with modern OpenGL context) - imgui_impl_opengl3.cpp ; OpenGL 3/4, OpenGL ES 2, OpenGL ES 3 (modern programmable pipeline) - imgui_impl_vulkan.cpp ; Vulkan - -List of high-level Frameworks Backends in this repository: (combine Platform + Renderer) - - imgui_impl_allegro5.cpp - imgui_impl_marmalade.cpp - -Note that Dear ImGui works with Emscripten. The examples_emscripten/ app uses imgui_impl_sdl.cpp and -imgui_impl_opengl3.cpp, but other combinations are possible. - -Third-party framework, graphics API and languages backends are listed at: - - https://github.com/ocornut/imgui/wiki/Bindings - -Including backends for: - - AGS/Adventure Game Studio, Amethyst, bsf, Cinder, Cocos2d-x, Diligent Engine, Flexium, - GML/Game Maker Studio2, GTK3+OpenGL3, Irrlicht Engine, LÖVE+LUA, Magnum, NanoRT, Nim Game Lib, - Ogre, openFrameworks, OSG/OpenSceneGraph, Orx, px_render, Qt/QtDirect3D, SFML, Sokol, - Unreal Engine 4, vtk, Win32 GDI, etc. - -Not sure which to use? -Recommended platform/frameworks: - - GLFW https://github.com/glfw/glfw Use imgui_impl_glfw.cpp - SDL2 https://www.libsdl.org Use imgui_impl_sdl.cpp - Sokol https://github.com/floooh/sokol Use util/sokol_imgui.h in Sokol repository. - -Those will allow you to create portable applications and will solve and abstract away many issues. +If you are using of the backend provided here, you can add the backends/imgui_impl_xxxx(.cpp,.h) +files to your project and use as-in. Each imgui_impl_xxxx.cpp file comes with its own individual +Changelog, so if you want to update them later it will be easier to catch up with what changed. --------------------------------------- EXAMPLE APPLICATIONS --------------------------------------- -Building: - Unfortunately in 2020 it is still tedious to create and maintain portable build files using external - libraries (the kind we're using here to create a window and render 3D triangles) without relying on - third party software. For most examples here we choose to provide: - - Makefiles for Linux/OSX - - Batch files for Visual Studio 2008+ - - A .sln project file for Visual Studio 2012+ - - Xcode project files for the Apple examples - Please let us know if they don't work with your setup! - You can probably just import the imgui_impl_xxx.cpp/.h files into your own codebase or compile those - directly with a command-line compiler. - - If you are interested in using Cmake to build and links examples, see: - https://github.com/ocornut/imgui/pull/1713 and https://github.com/ocornut/imgui/pull/3027 - - example_allegro5/ Allegro 5 example. = main.cpp + imgui_impl_allegro5.cpp @@ -290,3 +199,45 @@ example_win32_directx12/ DirectX12 example, Windows only. = main.cpp + imgui_impl_win32.cpp + imgui_impl_dx12.cpp This is quite long and tedious, because: DirectX12. + + +--------------------------------------- + MISCELLANEOUS +--------------------------------------- + +Building: + Unfortunately in 2020 it is still tedious to create and maintain portable build files using external + libraries (the kind we're using here to create a window and render 3D triangles) without relying on + third party software. For most examples here we choose to provide: + - Makefiles for Linux/OSX + - Batch files for Visual Studio 2008+ + - A .sln project file for Visual Studio 2012+ + - Xcode project files for the Apple examples + Please let us know if they don't work with your setup! + You can probably just import the imgui_impl_xxx.cpp/.h files into your own codebase or compile those + directly with a command-line compiler. + + If you are interested in using Cmake to build and links examples, see: + https://github.com/ocornut/imgui/pull/1713 and https://github.com/ocornut/imgui/pull/3027 + +Things feeling laggy? + + Dear ImGui has no particular extra lag for most behaviors, + e.g. the value of 'io.MousePos' provided at the time of NewFrame() will result in windows being moved + to the right spot at the time of EndFrame()/Render(). At 60 FPS your experience should be pleasant. + + However, consider that OS mouse cursors are typically drawn through a very specific hardware accelerated + path and will feel smoother than the majority of contents rendered via regular graphics API (including, + but not limited to Dear ImGui windows). Because UI rendering and interaction happens on the same plane + as the mouse, that disconnect may be jarring to particularly sensitive users. + You may experiment with enabling the io.MouseDrawCursor flag to request Dear ImGui to draw a mouse cursor + using the regular graphics API, to help you visualize the difference between a "hardware" cursor and a + regularly rendered software cursor. + However, rendering a mouse cursor at 60 FPS will feel sluggish so you likely won't want to enable that at + all times. It might be beneficial for the user experience to switch to a software rendered cursor _only_ + when an interactive drag is in progress. + + Note that some setup or GPU drivers are likely to be causing extra display lag depending on their settings. + If you feel that dragging windows feels laggy and you are not sure what the cause is: try to build a simple + drawing a flat 2D shape directly under the mouse cursor! +