[Solved] OpenGL Threading issues

mzanin

11-08-2010 07:55:12

Hello,

I have a working DirectX (multi-threaded) application which I now have to extend to support OpenGL. That's gonna be easy I thought. If only I knew how wrong I was.
Basically it seems that all API calls to OGRE (with OpenGL) must be made on the same thread.
If any Ogre calls are made on different threads I constantly get:


System.AccessViolationException


and the application crashes (even when you have try/catch blocks around the code).

So it doesn't tell me anything at all....

Is there a way to get this working without converting the whole rendering system into a single threaded system (not possible in my case)?

Would enabling multi-threading in Ogre fix this issue?


A simple example of what I'm talking about...
This works:


private void OnTimer(object state)
{
Dispatcher.BeginInvoke((Action) delegate
{
m_OgreRoot.RenderSystem.ClearFrameBuffer((uint) FrameBufferType.FBT_DEPTH, ColourValue.ZERO, 1, 0);
m_OgreRoot.RenderSystem._setDepthBias(0.001f);

var renderWindow = m_OgreRoot.Root.GetRenderTarget("boo");

if (renderWindow != null)
{
m_OgreRoot.Root._fireFrameStarted();

renderWindow._beginUpdate();
renderWindow._updateAutoUpdatedViewports(true);
renderWindow._endUpdate();

renderWindow.SwapBuffers();

m_OgreRoot.Root._fireFrameEnded();
}
});
}


This doesn't:


private void OnTimer(object state)
{
m_OgreRoot.RenderSystem.ClearFrameBuffer((uint) FrameBufferType.FBT_DEPTH, ColourValue.ZERO, 1, 0);
m_OgreRoot.RenderSystem._setDepthBias(0.001f);

Dispatcher.BeginInvoke((Action) delegate
{
var renderWindow = m_OgreRoot.Root.GetRenderTarget("boo");

if (renderWindow != null)
{
m_OgreRoot.Root._fireFrameStarted();

renderWindow._beginUpdate();
renderWindow._updateAutoUpdatedViewports(true);
renderWindow._endUpdate();

renderWindow.SwapBuffers();

m_OgreRoot.Root._fireFrameEnded();
}
});
}


Only difference the render system calls are outside the Dispatcher.BeginInvoke

mzanin

11-08-2010 09:24:41

Ok well, I guess it's a known issue.

I realised I can just write a SingleThreadedDispatcher, which will invoke all my render calls on the same render thread.

But I still would like to know why rendering on different threads works with DirectX and not OpenGL.
Call it curiosity if you will.

mikael

12-08-2010 16:04:45

Copied this from somewhere,
"Problems with multi-threading in OpenGL stem from its state machine architecture."
It might cause problems when you change states when rendering, I think this is why opengl does not support multi-threading.

However, dont know how DX do it way if it works.

But, only 1 rendering thread, other to calculate AI, etc.. or so :)

mzanin

25-08-2010 17:28:55

Sorry I didn't see your post.
Ok well if that's the case with OpenGL then it makes sense.
Well after changing over to a single threaded system it seems a bit more stable now :)

Thanks.