void OgreRTTexture::begin() { Ogre::RenderTexture* rtt = mTexture->getBuffer()->getRenderTarget(); if (mViewport == nullptr) { mViewport = rtt->addViewport(nullptr); mViewport->setClearEveryFrame(false); mViewport->setOverlaysEnabled(false); } Ogre::RenderSystem* system = Ogre::Root::getSingleton().getRenderSystem(); system->_setProjectionMatrix(mProjectMatrix); mSaveViewport = system->_getViewport(); system->_setViewport(mViewport); system->clearFrameBuffer(Ogre::FBT_COLOUR, Ogre::ColourValue::ZERO); }
void OgreImGui::renderQueueEnded(Ogre::uint8 queueGroupId, const Ogre::String& invocation,bool& repeatThisInvocation) { if ((queueGroupId != Ogre::RENDER_QUEUE_OVERLAY) || (invocation == "SHADOWS")) { return; } Ogre::RenderSystem* renderSys = Ogre::Root::getSingletonPtr()->getRenderSystem(); Ogre::Viewport* vp = renderSys->_getViewport(); if ((vp == nullptr) || (!vp->getTarget()->isPrimary()) || mFrameEnded) { return; } mFrameEnded = true; ImGui::Render(); this->updateVertexData(); ImGuiIO& io = ImGui::GetIO(); // Construct projection matrix, taking texel offset corrections in account (important for DirectX9) // See also: // - OGRE-API specific hint: http://www.ogre3d.org/forums/viewtopic.php?f=5&p=536881#p536881 // - IMGUI Dx9 demo solution: https://github.com/ocornut/imgui/blob/master/examples/directx9_example/imgui_impl_dx9.cpp#L127-L138 const float texelOffsetX = renderSys->getHorizontalTexelOffset(); const float texelOffsetY = renderSys->getVerticalTexelOffset(); const float L = texelOffsetX; const float R = io.DisplaySize.x + texelOffsetX; const float T = texelOffsetY; const float B = io.DisplaySize.y + texelOffsetY; Ogre::Matrix4 projMatrix( 2.0f/(R-L), 0.0f, 0.0f, (L+R)/(L-R), 0.0f, -2.0f/(B-T), 0.0f, (T+B)/(B-T), 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); mPass->getVertexProgramParameters()->setNamedConstant("ProjectionMatrix", projMatrix); for(std::list<ImGUIRenderable*>::iterator it = mRenderables.begin(); it!=mRenderables.end(); ++it) { mSceneMgr->_injectRenderWithPass(mPass, (*it), false, false, nullptr); } }
void OgreImGui::Render() { // Construct projection matrix, taking texel offset corrections in account (important for DirectX9) // See also: // - OGRE-API specific hint: http://www.ogre3d.org/forums/viewtopic.php?f=5&p=536881#p536881 // - IMGUI Dx9 demo solution: https://github.com/ocornut/imgui/blob/master/examples/directx9_example/imgui_impl_dx9.cpp#L127-L138 ImGuiIO& io = ImGui::GetIO(); Ogre::RenderSystem* renderSys = Ogre::Root::getSingletonPtr()->getRenderSystem(); const float texelOffsetX = renderSys->getHorizontalTexelOffset(); const float texelOffsetY = renderSys->getVerticalTexelOffset(); const float L = texelOffsetX; const float R = io.DisplaySize.x + texelOffsetX; const float T = texelOffsetY; const float B = io.DisplaySize.y + texelOffsetY; Ogre::Matrix4 projMatrix( 2.0f/(R-L), 0.0f, 0.0f, (L+R)/(L-R), 0.0f, -2.0f/(B-T), 0.0f, (T+B)/(B-T), 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); mPass->getVertexProgramParameters()->setNamedConstant("ProjectionMatrix", projMatrix); // Instruct ImGui to Render() and process the resulting CmdList-s /// Adopted from https://bitbucket.org/ChaosCreator/imgui-ogre2.1-binding /// ... Commentary on OGRE forums: http://www.ogre3d.org/forums/viewtopic.php?f=5&t=89081#p531059 ImGui::Render(); ImDrawData* draw_data = ImGui::GetDrawData(); Ogre::Viewport* vp = renderSys->_getViewport(); int vpWidth = vp->getActualWidth(); int vpHeight = vp->getActualHeight(); for (int i = 0; i < draw_data->CmdListsCount; ++i) { const ImDrawList* draw_list = draw_data->CmdLists[i]; unsigned int startIdx = 0; for (int j = 0; j < draw_list->CmdBuffer.Size; ++j) { // Create a renderable and fill it's buffers ImGUIRenderable renderable; const ImDrawCmd *drawCmd = &draw_list->CmdBuffer[j]; renderable.updateVertexData(draw_list->VtxBuffer.Data, &draw_list->IdxBuffer.Data[startIdx], draw_list->VtxBuffer.Size, drawCmd->ElemCount); // Set scissoring int scLeft = static_cast<int>(drawCmd->ClipRect.x); // Obtain bounds int scTop = static_cast<int>(drawCmd->ClipRect.y); int scRight = static_cast<int>(drawCmd->ClipRect.z); int scBottom = static_cast<int>(drawCmd->ClipRect.w); scLeft = scLeft < 0 ? 0 : (scLeft > vpWidth ? vpWidth : scLeft); // Clamp bounds to viewport dimensions scRight = scRight < 0 ? 0 : (scRight > vpWidth ? vpWidth : scRight); scTop = scTop < 0 ? 0 : (scTop > vpHeight ? vpHeight : scTop); scBottom = scBottom < 0 ? 0 : (scBottom > vpHeight ? vpHeight : scBottom); renderSys->setScissorTest(true, scLeft, scTop, scRight, scBottom); // Render! mSceneMgr->_injectRenderWithPass(mPass, &renderable, false, false, nullptr); // Update counts startIdx += drawCmd->ElemCount; } } renderSys->setScissorTest(false); }