OgreRTTexture::OgreRTTexture(Ogre::TexturePtr _texture) : mViewport(nullptr), mSaveViewport(nullptr), mTexture(_texture) { mProjectMatrix = Ogre::Matrix4::IDENTITY; Ogre::Root* root = Ogre::Root::getSingletonPtr(); if (root != nullptr) { Ogre::RenderSystem* system = root->getRenderSystem(); if (system != nullptr) { size_t width = mTexture->getWidth(); size_t height = mTexture->getHeight(); mRenderTargetInfo.maximumDepth = system->getMaximumDepthInputValue(); mRenderTargetInfo.hOffset = system->getHorizontalTexelOffset() / float(width); mRenderTargetInfo.vOffset = system->getVerticalTexelOffset() / float(height); mRenderTargetInfo.aspectCoef = float(height) / float(width); mRenderTargetInfo.pixScaleX = 1.0f / float(width); mRenderTargetInfo.pixScaleY = 1.0f / float(height); } if (mTexture->getBuffer()->getRenderTarget()->requiresTextureFlipping()) { mProjectMatrix[1][0] = -mProjectMatrix[1][0]; mProjectMatrix[1][1] = -mProjectMatrix[1][1]; mProjectMatrix[1][2] = -mProjectMatrix[1][2]; mProjectMatrix[1][3] = -mProjectMatrix[1][3]; } } }
void RenderedCompassImpl::_setCompass(Compass* compass) { Ogre::MaterialPtr originalMaterial = static_cast<Ogre::MaterialPtr>(Ogre::MaterialManager::getSingleton().getByName(mMaterialName)); if (originalMaterial) { originalMaterial->load(); mCompassMaterial = originalMaterial->clone(OgreInfo::createUniqueResourceName(originalMaterial->getName())); if (Ogre::Technique* tech = mCompassMaterial->getBestTechnique()) { Ogre::Pass* pass = nullptr; if (tech->getNumPasses() && (pass = tech->getPass(0))) { mCompassMaterialMapTUS = pass->getTextureUnitState("Background"); if (mCompassMaterialMapTUS) { //Make sure that the compass material is using the map texture for the base rendering mCompassMaterialMapTUS->setTexture(mMap->getTexture()); mTexture = Ogre::TextureManager::getSingleton().createManual("RenderedCompass", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, 128, 128, 1, Ogre::PF_A8R8G8B8, Ogre::TU_RENDERTARGET); mRenderTexture = mTexture->getBuffer()->getRenderTarget(); mRenderTexture->removeAllViewports(); mRenderTexture->setAutoUpdated(false); mRenderTexture->setActive(true); mCamera = mSceneManager->createCamera("RenderedCompassCamera"); mViewport = mRenderTexture->addViewport(mCamera); mViewport->setOverlaysEnabled(false); mViewport->setShadowsEnabled(false); mViewport->setSkiesEnabled(false); mViewport->setClearEveryFrame(true); mViewport->setBackgroundColour(Ogre::ColourValue::ZERO); mMapRectangle = OGRE_NEW Ogre::Rectangle2D(true); auto mapMaterialPtr = Ogre::MaterialManager::getSingleton().getByName(mCompassMaterial->getName(), Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); if (mapMaterialPtr) { mMapRectangle->setMaterial(mapMaterialPtr); } //We need to maximise the rendered texture to cover the whole screen Ogre::RenderSystem* rs = Ogre::Root::getSingleton().getRenderSystem(); Ogre::Real hOffset = rs->getHorizontalTexelOffset() / (0.5 * mViewport->getActualWidth()); Ogre::Real vOffset = rs->getVerticalTexelOffset() / (0.5 * mViewport->getActualHeight()); mMapRectangle->setCorners(-1 + hOffset, 1 - vOffset, 1 + hOffset, -1 - vOffset); //Since a Rectangle2D instance is a moveable object it won't be rendered unless it's in the frustrum. If we set the axis aligned box to be "infinite" it will always be rendered. Ogre::AxisAlignedBox aabInf; aabInf.setInfinite(); mMapRectangle->setBoundingBox(aabInf); //We can't attach something to the root node, so we'll attach it to a newly created node. We won't keep a reference to this node since it will be destroyed along with the scene manager when we ourselves are destroyed. mSceneManager->getRootSceneNode()->createChildSceneNode()->attachObject(mMapRectangle); //Return early since everything is good. return; } } } } S_LOG_WARNING("Could not load material '" << mMaterialName << "' for the compass."); }
void updateRenderInfo() { if (mRenderSystem != nullptr) { mInfo.maximumDepth = mRenderSystem->getMaximumDepthInputValue(); mInfo.hOffset = mRenderSystem->getHorizontalTexelOffset() / float(mViewSize.width); mInfo.vOffset = mRenderSystem->getVerticalTexelOffset() / float(mViewSize.height); mInfo.aspectCoef = float(mViewSize.height) / float(mViewSize.width); mInfo.pixScaleX = 1.0f / float(mViewSize.width); mInfo.pixScaleY = 1.0f / float(mViewSize.height); } }
void LayerManager::_windowResized(const FloatSize& _size) { // новый размер mViewSize = _size; mPixScaleX = 1.0 / _size.width; mPixScaleY = 1.0 / _size.height; mAspectCoef = _size.height / _size.width; Ogre::RenderSystem * render = Ogre::Root::getSingleton().getRenderSystem(); mHOffset = render->getHorizontalTexelOffset() / _size.width; mVOffset = render->getVerticalTexelOffset() / _size.height; // обновить всех mUpdate = true; }
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); }