The code is really threaded!!! I can do keyboard I/O (in particular "I") in the terminal window during the rendering of IRRLicht window...
I'm going to quickly explain my code:
- - the main program creates an object named "Viewer"
- the "Viewer" is the second thread
- the "Viewer" class creates a IRRLicht windows and has a public method "SetTestScene()" that should draw some test stuff like example 04.
- the Viewer class is an implementation of a Thread class created by a friend of mine that has 2 public methods: start() and stop(). When start is called the code inside the "work()" protected method is executed.
Main
Code: Select all
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <iostream>
#include <cstdlib>
#include "Viewer.h"
using namespace std;
int main(int argc, char *argv[])
{
Viewer* myViewer = new Viewer(); //Here starts the 2nd thread
myViewer->SetTestScene();
cout << "Hello, world!" << endl;
return 0;
}
Viewer.h
Code: Select all
class Viewer : public Thread
{
public:
Viewer();
~Viewer();
void SetTestScene();
protected:
void work() throw(); //When the thread is start()ed this method runs...
//It's like the thread "main()"...
private:
scene::ISceneManager* smgr;
IrrlichtDevice* device;
video::IVideoDriver* driver;
ConditionVariable cond;
bool cond_value;
void Initialize();
};
Viewer.cpp
Code: Select all
#include <stdio.h>
#include <wchar.h>
#include "Viewer.h"
#include "Thread.h"
#pragma comment(lib, "Irrlicht.lib")
using namespace irr;
Viewer::Viewer() : cond_value(false)
{
start();
}
Viewer::~Viewer()
{
stop();
join();
}
void Viewer::Initialize()
{
device = 0;
device = createDevice(video::EDT_OPENGL, core::dimension2d<s32>(640, 480),16, false, false, false);
driver = device->getVideoDriver();
smgr = device->getSceneManager();
//Without these instructions I have the segm fault in the SetTestScene()
// video::ITexture* _text1 = driver->getTexture("wall.bmp");
// video::ITexture* _text2 = driver->getTexture("t351sml.jpg");
// video::ITexture* _text3 = driver->getTexture("sydney.bmp");
}
void Viewer::SetTestScene() //The same scene of example 04
{
cond.lock();
cond.wait(cond_value);
video::ITexture* texture1 = driver->getTexture("wall.bmp");
video::ITexture* texture2 = driver->getTexture("t351sml.jpg");
video::ITexture* texture3 = driver->getTexture("sydney.bmp");
scene::ISceneNode* node = 0;
node = smgr->addTestSceneNode();
node->setPosition(core::vector3df(0,0,30));
node->setMaterialTexture(0, texture1);
scene::ISceneNode* n = smgr->addTestSceneNode();
n->setMaterialTexture(0, texture2);
scene::ISceneNodeAnimator* anim = smgr->createFlyCircleAnimator(core::vector3df(0,0,30), 20.0f);
n->addAnimator(anim);
anim->drop();
scene::IAnimatedMeshSceneNode* anms = smgr->addAnimatedMeshSceneNode(smgr->getMesh("sydney.md2"));
if (n)
{
anim = smgr->createFlyStraightAnimator(core::vector3df(100,0,60),
core::vector3df(-100,0,60), 10000, true);
anms->addAnimator(anim);
anim->drop();
anms->setMaterialFlag(video::EMF_LIGHTING, false);
anms->setFrameLoop(320, 360);
anms->setAnimationSpeed(30);
anms->setRotation(core::vector3df(0,180.0f,0));
anms->setMaterialTexture(0, texture3);
}
cond.unlock();
}
void Viewer::work() throw() //The main of second thread...
{
Initialize();
smgr->addCameraSceneNodeFPS(0, 100.0f, 100.0f);
device->getCursorControl()->setVisible(false);
while(device->run())
{
cond.lock();
driver->beginScene(true, true, Video::SColor(255,113,113,133));
smgr->drawAll();
driver->endScene();
cond_value = true;
cond.signal();
cond.unlock();
}
device->drop();
}
Thread.h
Code: Select all
#ifndef Thread_h
#define Thread_h
#include <pthread.h>
class Thread
{
public:
virtual ~Thread() {}
void start();
void stop();
void join();
protected:
virtual void work() throw() = 0;
private:
pthread_t threadId;
static void* threadHandler(void* arg);
};
class ConditionVariable
{
public:
ConditionVariable() { pthread_mutex_init(&mtx,NULL); pthread_cond_init(&cond,NULL); }
~ConditionVariable() { pthread_cond_destroy(&cond); pthread_mutex_destroy(&mtx); }
void lock() { pthread_mutex_lock(&mtx); }
void unlock() { pthread_mutex_unlock(&mtx); }
void signal() { pthread_cond_signal(&cond); }
void wait( const volatile bool& condition );
private:
pthread_mutex_t mtx;
pthread_cond_t cond;
};
#endif // Thread_h
Thread.cpp
Code: Select all
#include "Thread.h"
void Thread::start()
{
pthread_create(&threadId, NULL, &Thread::threadHandler, this);
}
void Thread::stop()
{
pthread_cancel(threadId);
}
void Thread::join()
{
pthread_join(threadId, NULL);
}
void* Thread::threadHandler(void* arg)
{
Thread* t = static_cast<Thread*>(arg);
t->work();
return NULL;
}
void ConditionVariable::wait( const volatile bool& condition )
{
while ( !condition )
pthread_cond_wait( &cond, &mtx );
}