As slicky requested, here is how I integrated ImGui with Ogre 2.2. Note that I've only implemented DX11, but it should be similar for OpenGL.
Code: Select all
#include "OgreImGuiBindings.h"
#include "OgreRoot.h"
#include "OgreWindow.h"
#include "OgreRenderPassDescriptor.h"
#include "imgui.h"
#include "imgui_impl_dx11.h"
#include <d3d11_1.h>
static Ogre::Window *g_ogreRenderWindow = nullptr;
static ID3D11Device* g_pd3dDevice = nullptr;
static ID3D11DeviceContext* g_pImmediateContext = nullptr;
static Ogre::RenderPassDescriptor *renderPassDesc = nullptr;
static void beginRenderPassDescriptor() {
Ogre::RenderSystem* system = Ogre::Root::getSingleton().getRenderSystem();
if (!renderPassDesc) {
renderPassDesc = system->createRenderPassDescriptor();
renderPassDesc->mColour[0].texture = g_ogreRenderWindow->getTexture();
renderPassDesc->mColour[0].loadAction = Ogre::LoadAction::Load;
renderPassDesc->mColour[0].storeAction = Ogre::StoreAction::StoreOrResolve;
renderPassDesc->mDepth.texture = g_ogreRenderWindow->getDepthBuffer();
renderPassDesc->mDepth.loadAction = Ogre::LoadAction::Load;
renderPassDesc->mDepth.storeAction = Ogre::StoreAction::DontCare;
renderPassDesc->mStencil.texture = g_ogreRenderWindow->getStencilBuffer();
renderPassDesc->mStencil.loadAction = Ogre::LoadAction::Load;
renderPassDesc->mStencil.storeAction = Ogre::StoreAction::DontCare;
renderPassDesc->entriesModified(Ogre::RenderPassDescriptor::All);
}
Ogre::Vector4 viewportSize(0, 0, 1, 1);
Ogre::Vector4 scissors(0, 0, 1, 1);
system->beginRenderPassDescriptor(renderPassDesc, g_ogreRenderWindow->getTexture(), viewportSize, scissors, false, false);
}
static void endRenderPassDescriptor() {
Ogre::RenderSystem* system = Ogre::Root::getSingleton().getRenderSystem();
system->endRenderPassDescriptor();
}
void ImGui_NewFrame() {
ImGui_ImplDX11_NewFrame();
}
void ImGui_Render() {
beginRenderPassDescriptor();
ImGui::Render();
endRenderPassDescriptor();
}
extern LRESULT ImGui_ImplDX11_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void ImGui_Init(void* renderWindow)
{
g_ogreRenderWindow = (Ogre::Window*)renderWindow;
g_pd3dDevice = nullptr;
g_pImmediateContext = nullptr;
g_ogreRenderWindow->getCustomAttribute("D3DDEVICE", &g_pd3dDevice);
g_pd3dDevice->GetImmediateContext(&g_pImmediateContext);
g_ogreRenderWindow->getCustomAttribute("D3DDEVICE", &g_pd3dDevice);
HWND hwnd = 0;
g_ogreRenderWindow->getCustomAttribute("WINDOW", &hwnd);
ImGui_ImplDX11_Init(hwnd, g_pd3dDevice, g_pImmediateContext);
}
void ImGui_Shutdown()
{
Ogre::RenderSystem* system = Ogre::Root::getSingleton().getRenderSystem();
system->destroyRenderPassDescriptor(renderPassDesc);
renderPassDesc = nullptr;
ImGui_ImplDX11_Shutdown();
}
In order to support keyboard/mouse input, you also need to call ImGui_ImplDX11_WndProcHandler() at the beginning of your windowProc.
One tricky part is when your mouse clikced in ImGui's window, it should not be passed to Ogre anymore. Here is how I solve this:
Code: Select all
LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (ImGui_ImplDX11_WndProcHandler(hWnd, uMsg, wParam, lParam)) {
if (ImGui::IsAnyWindowHovered()) return true;
}
...