OGRE Wiki
Support and community documentation for Ogre3D
Ogre Forums
ogre3d.org
Log in
Username:
Password:
CapsLock is on.
Remember me (for 1 year)
Log in
Home
Tutorials
Tutorials Home
Basic Tutorials
Intermediate Tutorials
Mad Marx Tutorials
In Depth Tutorials
Older Tutorials
External Tutorials
Cookbook
Cookbook Home
CodeBank
Snippets
Experiences
Ogre Articles
Libraries
Libraries Home
Alternative Languages
Assembling A Toolset
Development Tools
OGRE Libraries
List of Libraries
Tools
Tools Home
DCC Tools
DCC Tutorials
DCC Articles
DCC Resources
Assembling a production pipeline
Development
Development Home
Roadmap
Building Ogre
Installing the Ogre SDK
Setting Up An Application
Ogre Wiki Tutorial Framework
Frequently Asked Questions
Google Summer Of Code
Help Requested
Ogre Core Articles
Community
Community Home
Projects Using Ogre
Recommended Reading
Contractors
Wiki
Immediate Wiki Tasklist
Wiki Ideas
Wiki Guidelines
Article Writing Guidelines
Wiki Styles
Wiki Page Tracker
Ogre Wiki Help
Ogre Wiki Help Overview
Help - Basic Syntax
Help - Images
Help - Pages and Structures
Help - Wiki Plugins
Toolbox
Freetags
Categories
List Pages
Structures
Trackers
Statistics
Rankings
List Galleries
Ogre Lexicon
Comments
History: Threading
View page
Source of version: 8
(current)
! User comments This is mainly just a rewording of [http://www.ogre3d.org/forums/viewtopic.php?t=7244|this forum thread] (year 2005) so go there for the full answer. --- {QUOTE(replyto="Sinbad")}You should thread things that naturally fall into the background, ie to be spread over multiple frames. That's AI, buffering of streaming data, but probably not physics (because you need to keep it in sync with the frame rate if it's not going to look weird). None of these things are Ogre itself. Due to the fact that the graphics are the most noticeable thing, and that the GPU is asynchronous anyway, rendering processes are rarely farmed out to the background, so there's generally no need for thread safety. Projects which use threading thread non-graphical things. The one case where it might be useful is background loading using the resource system. In Azathoth the resource system is (experimentally) thread safe if you set OGRE_THREAD_SUPPORT to 1, allowing you to load things in a background thread if you want. But that's only the resource system, nothing else is thread safe, and in my opinion has no need to be. We use [http://www.boost.org/doc/html/threads.html|boost::threads] for this, personally it seemed a much better solution than anything else I've seen (it reminds me of Java threads).{QUOTE} --- {QUOTE(replyto="AlphaBeta")}Keep in mind you don't need threads to run systems at varying rates (keep countdowns, if time is up step the system, if not move on). If you're using ogre for a game threading isn't really necessary (like sinbad said, graphics are already asynchronous). For things like physics, multi-steps are often done (instead of updating the physics simulation 30 milliseconds, you might have it do 15 milliseconds 2 times. Physics simulations get less accurate with bigger updates, which doesn't apply to most other systems). You wouldn't want to simply run a physics update multiple times for each graphics one, you should work it out with timers and countdowns.{QUOTE} --- {QUOTE(replyto="QSilver")}I should point out that even though Ogre is not thread-safe, there is no reason why your application cannot use threads. It just means that you cannot have multiple threads which deal with Ogre. As long as you make sure that only a single thread handles all your Ogre-related tasks, you are free to run your sound engine or AI scripts in other threads.{QUOTE} ! Example This example is based on the Tutorial Framework and displays the ogre head. The orientation of the head is calculated in a new thread using boost. The result is used in main thread to rotate the head. This example is working since OGRE 1.9. __TutorialApplication.h__ {CODE(wrap="1", colors="c++")}/* ----------------------------------------------------------------------------- Filename: TutorialApplication.h ----------------------------------------------------------------------------- This source file is part of the ___ __ __ _ _ _ /___\__ _ _ __ ___ / / /\ \ (_) | _(_) // // _` | '__/ _ \ \ \/ \/ / | |/ / | / \_// (_| | | | __/ \ /\ /| | <| | \___/ \__, |_| \___| \/ \/ |_|_|\_\_| |___/ Tutorial Framework http://www.ogre3d.org/tikiwiki/ ----------------------------------------------------------------------------- */ #ifndef __TutorialApplication_h_ #define __TutorialApplication_h_ #include "BaseApplication.h" #include <boost/thread/thread.hpp> #include <boost/thread/mutex.hpp> #include <boost/shared_ptr.hpp> #include <boost/random/linear_congruential.hpp> #include <boost/random/uniform_real.hpp> #include <boost/random/variate_generator.hpp> #include <boost/generator_iterator.hpp> class TutorialApplication : public BaseApplication { private: boost::shared_ptr<boost::thread> mThread; Ogre::SceneNode* mHeadNode; Ogre::Real mAngle; boost::mutex mMutex; public: TutorialApplication(void); virtual ~TutorialApplication(void); protected: virtual void createScene(void); virtual void destroyScene(void); virtual bool frameStarted(const Ogre::FrameEvent& evt); private: void runThread(); }; #endif // #ifndef __TutorialApplication_h_ {CODE} __TutorialApplication.cpp__ {CODE(wrap="1", colors="c++")}/* ----------------------------------------------------------------------------- Filename: TutorialApplication.cpp ----------------------------------------------------------------------------- This source file is part of the ___ __ __ _ _ _ /___\__ _ _ __ ___ / / /\ \ (_) | _(_) // // _` | '__/ _ \ \ \/ \/ / | |/ / | / \_// (_| | | | __/ \ /\ /| | <| | \___/ \__, |_| \___| \/ \/ |_|_|\_\_| |___/ Tutorial Framework http://www.ogre3d.org/tikiwiki/ ----------------------------------------------------------------------------- */ #include "TutorialApplication.h" //------------------------------------------------------------------------------------- TutorialApplication::TutorialApplication(void) : mHeadNode(NULL) , mAngle(0.0f) { } //------------------------------------------------------------------------------------- TutorialApplication::~TutorialApplication(void) { } //------------------------------------------------------------------------------------- void TutorialApplication::createScene(void) { // Set the scene's ambient light mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f)); // Create an Entity Ogre::Entity* ogreHead = mSceneMgr->createEntity("ogrehead.mesh"); // Create a SceneNode and attach the Entity to it #if OGRE_VERSION >= ((2 << 16) | (0 << 8) | 0) mHeadNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); #else mHeadNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("HeadNode"); #endif mHeadNode->attachObject(ogreHead); // Create a Light and set its position #if OGRE_VERSION >= ((2 << 16) | (0 << 8) | 0) Ogre::Light* light = mSceneMgr->createLight(); Ogre::SceneNode* lightNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Ogre::SCENE_DYNAMIC, Ogre::Vector3(20.0f, 80.0f, 50.0f)); lightNode->attachObject(light); #else Ogre::Light* light = mSceneMgr->createLight("MainLight"); light->setPosition(20.0f, 80.0f, 50.0f); #endif // Create the thread and start work assert(!mThread); mThread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&TutorialApplication::runThread, this))); } //------------------------------------------------------------------------------------- void TutorialApplication::destroyScene(void) { // Stops the thread assert(mThread); mThread->join(); // Destroy scene BaseApplication::destroyScene(); } //------------------------------------------------------------------------------------- bool TutorialApplication::frameStarted(const Ogre::FrameEvent& evt) { // Lock mutex boost::unique_lock<boost::mutex> lock(mMutex); // Update Orientation mHeadNode->setOrientation(Ogre::Quaternion(Ogre::Radian(mAngle), Ogre::Vector3::UNIT_Y)); return true; } // Unlock mutex //------------------------------------------------------------------------------------- void TutorialApplication::runThread() { while(!mShutDown) { // Lock mutex boost::unique_lock<boost::mutex>* lock = new boost::unique_lock<boost::mutex>(mMutex); // Update data mAngle += 0.005f; // Unlock mutex delete lock; // Wait boost::this_thread::sleep(boost::posix_time::milliseconds(25)); } } #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 #define WIN32_LEAN_AND_MEAN #include "windows.h" #endif #ifdef __cplusplus extern "C" { #endif #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT ) #else int main(int argc, char *argv[]) #endif { // Create application object TutorialApplication app; try { app.go(); } catch( Ogre::Exception& e ) { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL); #else std::cerr << "An exception has occured: " << e.getFullDescription().c_str() << std::endl; #endif } return 0; } #ifdef __cplusplus } #endif {CODE}
Search by Tags
Search Wiki by Freetags
Latest Changes
IDE Eclipse
FMOD SoundManager
HDRlib
Building Ogre V2 with CMake
Ogre 2.1 FAQ
Minimal Ogre Collision
Artifex Terra
OpenMB
Advanced Mogre Framework
MogreSocks
...more
Search
Find
Advanced
Search Help
Online Users
148 online users