No support for "externalSwapChain" option in Ogre 2.1

Problems building or running the engine, queries about how to use features etc.
Post Reply
vcand
Gnoblar
Posts: 3
Joined: Wed Mar 14, 2018 10:00 am

No support for "externalSwapChain" option in Ogre 2.1

Post by vcand » Mon Nov 05, 2018 8:53 pm

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.
0 x

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 3996
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 191
Contact:

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

Post by dark_sylinc » Tue Nov 06, 2018 7:40 am

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
0 x

al2950
OGRE Expert User
OGRE Expert User
Posts: 1193
Joined: Thu Dec 11, 2008 7:56 pm
Location: Bristol, UK
x 74

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

Post by al2950 » Tue Nov 06, 2018 12:29 pm

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));
}
0 x

vcand
Gnoblar
Posts: 3
Joined: Wed Mar 14, 2018 10:00 am

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

Post by vcand » Tue Nov 06, 2018 9:00 pm

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.
0 x

User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 3996
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 191
Contact:

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

Post by dark_sylinc » Wed Nov 07, 2018 3:56 pm

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
0 x

Post Reply