Introduction

Ogre supports threee different thread support options: None, background resource loading and full thread support.
The default one is the first option (none). The second one seems to be most interessting one, because async resource loading makes it easy to implement an loading screen.
Because of this, this guide will focus on option two: background resource loading.

The "thread provider" will be Poco (alternatives are Boost and TPM). I chooosed Poco just because Boost caused some trouble with Mogre, nothing more. It is of course possible to use one of the other providers, only the names will change ;) .

Remarks

  • This is an advanced tutorial, not a really step-by-step bullet proof tutorial
  • Although I managed to compile (M)Ogre with Poco successfuly and also set up an test project, this guide is some how "theoretical".
    1. Ogre is not designed to be thread safe, because thread safety does not means "faster" but "more difficult to maintain" (in addistion there is an additional overhead). Thread safety is accomplished by using mutexes.
    2. Ogre 1.7.* (and higher) have a "bug". There is a race condition and possible dead lock caused by the mutexes in both the resource manager and D3D. As a result, as soon as you start your project, ogre freezes because it locked itself (and not only the background thread): both main thread and background thread are waiting for each other


Please keep that in mind.

Steps:

  1. Download poco from here, extract it somewhere (e.g. C:\) and compile it.
  2. We have to compile both mogre and ogre. For that we will use MogreBuilder. Compile it, too, and make sure that you can compile mogre without any modifications
  3. Start mogre builder and wait until it compiled the dependencies. Kill it now (completely).
  4. Open cmake-gui and navigate to the ogre source (e.g. C:\...\Main\OgreSrc\ogre\). The build directory will be "C:\...\Main\OgreSrc\build\" (you may need to create the directory).
  5. Press "configure" and fill in the fields for "Poco": POCO_INCLUDE_DIR = (The include dir of poco, e.g. "C:/poco-1.4.4/Foundation/include") and POCO_LIBRARY_DBG = (the PocoFoundationd.lib, e.g. "C:/poco-1.4.4/lib/PocoFoundationd.lib")
  6. Press "Generate" (if there are any erros, double check the paths)
  7. Copy the below patch and apply it. This modified Attributes.xml includes some fixes which include the class "ResourceBackgroundQueue" into the auto wrapper process and "restore" the workqueue id.
    diff -r c2be4e87dc8b Codegen/AutoWrap/Attributes.xml
    --- a/Codegen/AutoWrap/Attributes.xml	Wed Apr 18 02:28:03 2012 +0200
    +++ b/Codegen/AutoWrap/Attributes.xml	Tue Sep 11 11:09:44 2012 +0200
    @@ -215,7 +215,7 @@
         <class name="ControllerFunctionRealPtr" Ignore=""/>
         <class name="ManualResourceLoader" WrapType="Interface"/>
         <class name="MaterialSerializer" WrapType="PlainWrapper"/>
    -    <class name="ResourceBackgroundQueue" Ignore=""/>
    +    <!-- <class name="ResourceBackgroundQueue" Ignore=""/> -->
     
         <!-- to avoid name clash with System.Exception -->
         <class name="Exception" WrapType="PlainWrapper" ReadOnly="" Rename="OgreException">
    @@ -302,7 +302,15 @@
           <class name="Listener" WrapType="NativeDirector"/>
         </class>
         <class name="ResourceBackgroundQueue">
    -      <class name="Listener" WrapType="Interface"/>
    +	   <_CustomIncDeclaration>
    +			public: typedef unsigned long BackgroundProcessTicket&amp;
    +	  </_CustomIncDeclaration>
    +      <class name="Listener" WrapType="Interface">
    +	  </class>
    +	  <function name="canHandleRequest" Ignore=""/>
    +	  <function name="handleRequest" Ignore=""/>
    +	  <function name="canHandleResponse" Ignore=""/>
    +	  <function name="handleResponse" Ignore=""/>
         </class>
         <class name="SceneManager">
           <class name="SkyBoxGenParameters" WrapType="ReadOnlyStruct"/>
    @@ -898,8 +906,8 @@
           <_CustomIncPreDeclaration>
             public: typedef Ogre::WorkQueue::RequestID RequestID;
           </_CustomIncPreDeclaration>
    -      <typedef name="RequestID" Ignore="" />
    -      <function name="addRequest" Ignore="" />
    +      <typedef name="RequestID" ReplaceBy="unsigned long" />
    +      <!-- <function name="addRequest" Ignore="" /> -->
           <class name="Request" WrapType="PlainWrapper">
             <function name="Request" Ignore="" />
           </class>
  8. Open "C:\...\Main\OgreSrc\ogre\OgreMain\include\OgreConfig.h" and change
    #define OGRE_THREAD_SUPPORT 0
    to
    #define OGRE_THREAD_SUPPORT 1
    and
    #define OGRE_THREAD_PROVIDER 0
    to
    #define OGRE_THREAD_PROVIDER 2
    Save the file.
  9. Fire up MogreBuilder again and let it finish (if the AutoWrapper step is skipped, do it manually by starting "C:\...\Codegen\AutoWrap\bin\Debug\AutoWrap.exe" and pressing "Produce".


And that's it (do not forget to copy "PocoFoundationd.dll" into your app directory). Ogre now supports background resource loading (which is not working properly sad ).