Page 1 of 1

No support for "externalSwapChain" option in Ogre 2.1

Posted: Mon Nov 05, 2018 8:53 pm
by vcand
Ogre Version: :2.1:
Operating System: :Windows:
Render System: :Direct3D11:

We are porting our application to Ogre 2.1 and stumbled upon that the D3D11RenderWindow does not support the "externalSwapChain" option anymore. Is there any reason this support is removed? Is it no compatible with something in Ogre 2.1? We have used this option to implement support for VR and Mixed Reality systems so we can let their SDK handle the swap chain.

Re: No support for "externalSwapChain" option in Ogre 2.1

Posted: Tue Nov 06, 2018 7:40 am
by dark_sylinc
I can't find traces of that option at all in the history of D3D11RenderWindow in 1.x branches, so I'm afraid I don't know what feature are you talking about :?

Do you have a reference to see that "externalSwapChain" option so I can take a look?

Cheers
Matias

Re: No support for "externalSwapChain" option in Ogre 2.1

Posted: Tue Nov 06, 2018 12:29 pm
by al2950
If you are referring to using Oculus SDK and its 'external swap chain' with Ogre 2.1 its fairly easy, here are a few snippets from my engine:

setup oculus swap chain

Code: Select all

ovrTextureSwapChainDesc desc = {};
desc.Type = ovrTexture_2D;
desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
desc.ArraySize = 1;
desc.Width = rttWidth;
desc.Height = rttHeight;
desc.MipLevels = 1;
desc.SampleCount = masterRenderWindow->getFSAA();
desc.StaticImage = ovrFalse;
desc.MiscFlags = ovrTextureMisc_None;
desc.BindFlags = ovrTextureBind_DX_RenderTarget;


Ogre::D3D11RenderSystem* renderSystem = dynamic_cast<Ogre::D3D11RenderSystem*>(m_core.getOgreRoot()->getRenderSystem());

if (ovr_CreateTextureSwapChainDX(m_ovrSession, renderSystem->_getDevice().get(), &desc, &m_ovrTextureChain) == ovrSuccess)
{
    int count = 0;
    ovr_GetTextureSwapChainLength(m_ovrSession, m_ovrTextureChain, &count);
    m_swapChainTextures.resize(count);
    for (int i = 0; i < count; ++i)
    {
        ID3D11Texture2D* texture = nullptr;
        ovr_GetTextureSwapChainBufferDX(m_ovrSession, m_ovrTextureChain, i, IID_PPV_ARGS(&texture));
        renderSystem->_getDevice().get()->CreateRenderTargetView(texture, nullptr, &m_swapChainTextures[i]);
        texture->Release();
    }
}
setup Ogre compositor. NB I use a single texture for both left and right eyes

Code: Select all

m_rttTexture = Ogre::TextureManager::getSingleton().createManual("VR_RTT",
    Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, rttWidth, rttHeight, 0, Ogre::PF_A8B8G8R8, Ogre::TU_RENDERTARGET, (Ogre::ManualResourceLoader*)0
    , true, masterRenderWindow->getFSAA(), masterRenderWindow->getFSAAHint());

Ogre::CompositorChannel channel = Ogre::CompositorChannel();
channel.target = m_rttTexture->getBuffer(0)->getRenderTarget();
channel.textures.push_back(m_rttTexture);

const Ogre::IdString workspaceName(masterRenderWindow->getFSAA() > 1 ? "MyVrWorkspaceMSAA" : "MyVrWorkspace");
Ogre::CompositorManager2* compMgr = m_core.getOgreRoot()->getCompositorManager2();
Ogre::SceneManager* sceneMgr = m_core.getSceneManager();
m_eyeWorkspace = compMgr->addWorkspace(sceneMgr, Ogre::CompositorChannelVec{ channel }, m_eyeCameras[VRE_LEFT], Ogre::IdString(workspaceName), true, -1);

Then each frame copy the Ogre buffers to the Oculus swap chain

Code: Select all

//copy ogre textures to oculus swap chain
int currentIndex = 0;
ovr_GetTextureSwapChainCurrentIndex(m_ovrSession, m_ovrTextureChain, &currentIndex);

auto ogreTexture =  static_cast<Ogre::D3D11Texture*>(m_rttTexture.get());
ID3D11Resource* oculusTexture;
m_swapChainTextures[currentIndex]->GetResource(&oculusTexture);     

ID3D11DeviceContext* context;
Ogre::D3D11RenderSystem* renderSystem = dynamic_cast<Ogre::D3D11RenderSystem*>(m_core.getOgreRoot()->getRenderSystem());
renderSystem->_getDevice()->GetImmediateContext(&context);
context->CopyResource(oculusTexture, ogreTexture->GetTex2D());
ovrResult result = ovr_CommitTextureSwapChain(m_ovrSession, m_ovrTextureChain);
if (OVR_FAILURE(result))
{
    ovrErrorInfo errorInfo;
    ovr_GetLastErrorInfo(&errorInfo);
    m_core.logMessage("Oculus SDK Failed ovr_CommitTextureSwapChain: " + std::string(errorInfo.ErrorString));
}

ovrLayerHeader* layers = &m_ovrMainLayer.Header;
result = ovr_EndFrame(m_ovrSession, frameNum, nullptr, &layers, 1);
if (OVR_FAILURE(result))
{
    ovrErrorInfo errorInfo;
    ovr_GetLastErrorInfo(&errorInfo);
    m_core.logMessage("Oculus SDK Failed ovr_EndFrame: " + std::string(errorInfo.ErrorString));
}

Re: No support for "externalSwapChain" option in Ogre 2.1

Posted: Tue Nov 06, 2018 9:00 pm
by vcand
Hi @dark_sylinc,

I'm sorry to have wasted your time on this :( . It turns out that it was one of our own team members (no longer working with us) who added this option a long time ago to our own branch of 1.10 :oops:

When this option is on, the creation of the swapchain object in the render window will be disabled, and when the swapBuffers() method is invoked, it will just simply return. We use this option to toggle between rendering modes while having the same code base.

With that said, is this something you think would be useful for the general public? We could create and send in a PR in that case.

Re: No support for "externalSwapChain" option in Ogre 2.1

Posted: Wed Nov 07, 2018 3:56 pm
by dark_sylinc
I would like to take a look at it yes. It sounds like it could be useful.

First upload it to a fork to look at it so I can see how it works and what it does

Thanks
Cheers