In my small game engine I use manual objects to build my terrain from a heightmap.
It's working, but I encounter the common problem of the program freezing as my paging system loads in new data.
To overcome this, I am trying to implement boost threads.
Below is sample code from my program, simplified for readability.
- updateTerrain : Called from the main function about every second.
createTerrainUpdate : Builds terrain information and stores it in OgreTerra class variables.
renderTerrainUpdate : Updates the manual object using the above class variables.
Code: Select all
void [color=#4080FF]OgreTerra::updateTerrain[/color]() {
boost::thread createTerrainUpdateThread(boost::bind(&OgreTerra::createTerrainUpdate, this));
createTerrainUpdateThread.join();
renderTerrainUpdate();
}
Code: Select all
void [color=#4080FF]OgreTerra::renderTerrainUpdate[/color]() {
Ogre::ManualObject* manual = OgreFramework::getSingletonPtr()->m_pSceneMgr->getManualObject("big");
manual->beginUpdate(0);
for ( int k=0; k < segments[i].vertex_indices.size();) {
// Set the vertex positions.
manual->position(vertices[segments[i].vertex_indices[k]],vertices[segments[i].vertex_indices[k+1]],vertices[segments[i].vertex_indices[k+2]]);
// Set the normals
manual->normal(normals[segments[i].vertex_normals[n]]);
// Set the UVs
manual->textureCoord(a, b);
}
for ( int j=0; j < segments[i].triangle_indices.size();) {
manual->triangle(segments[i].triangle_indices[j],segments[i].triangle_indices[j+1],segments[i].triangle_indices[j+2]);
j=j+3;
}
manual->end();
This half solves my issue, however I still get subsecond stalls as renderTerrainUpdate is processed..
Now if rewrite updateTerrain to also fire renderTerrainUpdate as a boost thread as below..
Code: Select all
void [color=#4080FF]OgreTerra::updateTerrain[/color]() {
boost::thread createTerrainUpdateThread(boost::bind(&OgreTerra::createTerrainUpdate, this));
createTerrainUpdateThread.join();
boost::thread renderTerrainUpdateThread(boost::bind(&OgreTerra::renderTerrainUpdate, this));
renderTerrainUpdateThread.join();
}
start createTerrainUpdate
[New Thread 0x7fffd267e700 (LWP 4269)]
createTerrainUpdate - 64 , 4096 , 64
update started
[Thread 0x7fffd267e700 (LWP 4269) exited]
[New Thread 0x7fffd267e700 (LWP 4275)]
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffd267e700 (LWP 4275)]
0x00007fffeefb9069 in glGenBuffersARB () from /usr/lib64/libGL.so.1
(gdb) bt
#0 0x00007fffeefb9069 in glGenBuffersARB () from /usr/lib64/libGL.so.1
#1 0x00007fffef32d3b3 in Ogre::GLHardwareVertexBuffer::GLHardwareVertexBuffer(Ogre::HardwareBufferManagerBase*, unsigned long, unsigned long, Ogre::HardwareBuffer::Usage, bool) () from /usr/local/lib/OGRE/RenderSystem_GL.so
#2 0x00007fffef32647f in Ogre::GLHardwareBufferManagerBase::createVertexBuffer(unsigned long, unsigned long, Ogre::HardwareBuffer::Usage, bool) () from /usr/local/lib/OGRE/RenderSystem_GL.so
#3 0x00007fffef33bec5 in ?? () from /usr/local/lib/OGRE/RenderSystem_GL.so
#4 0x00007ffff6f607c4 in Ogre::ManualObject::end() () from /usr/lib64/libOgreMain.so.1.8.1
#5 0x0000000000442a23 in OgreTerra::renderTerrainUpdate (this=0x67c060 <myterrain>) at ogre/ogre_terrain.cc:499
#6 0x00000000004505f5 in boost::_mfi::mf0<void, OgreTerra>::operator() (this=0x165c870, p=0x67c060 <myterrain>)
at /usr/include/boost/bind/mem_fn_template.hpp:49
#7 0x0000000000450558 in boost::_bi::list1<boost::_bi::value<OgreTerra*> >::operator()<boost::_mfi::mf0<void, OgreTerra>, boost::_bi::list0> (this=0x165c880, f=..., a=...) at /usr/include/boost/bind/bind.hpp:253
#8 0x00000000004504cb in boost::_bi::bind_t<void, boost::_mfi::mf0<void, OgreTerra>, boost::_bi::list1<boost::_bi::value<OgreTerra*> > >::operator() (this=0x165c870) at /usr/include/boost/bind/bind_template.hpp:20
#9 0x0000000000450412 in boost::detail::thread_data<boost::_bi::bind_t<void, boost::_mfi::mf0<void, OgreTerra>, boost::_bi::list1<boost::_bi::value<OgreTerra*> > > >::run (this=0x165c6d0) at /usr/include/boost/thread/detail/thread.hpp:78
#10 0x00007ffff52b7af3 in ?? () from /usr/lib64/libboost_thread.so.1.52.0
#11 0x00007ffff6aa3c74 in start_thread () from /lib64/libpthread.so.0
#12 0x00007ffff4815b0d in clone () from /lib64/libc.so.6
ogre/ogre_terrain.cc:499 is manual->end(); in renderTerrainUpdate() .
I know ogre is not threadsafe like this, but what would be the recommended way to overcome this?
I am looking at the workqueue http://www.ogre3d.org/tikiwiki/tiki-ind ... +WorkQueue and I'll attempt that, but any feedback or comments on this would be appreciated.
edit: it seems this question was asked before http://www.ogre3d.org/forums/viewtopic.php?f=1&t=64291 , and points the issue being related to manual object!! Does this mean manual objects simple can not be used with threads?
Another topic http://www.ogre3d.org/forums/viewtopic.php?f=2&t=79387 shows a possible implementation in workqueue, does this allow for safe updating of manual objects?