To see this code running on youtube.. http://www.youtube.com/watch?v=5vvp-08yegI
Code: Select all
#include <irrlicht/irrlicht.h>
#include <opencv/cv.h>
#include <opencv/cxcore.h>
#include <opencv/highgui.h>
#include <time.h>
#include <sys/timeb.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
IrrlichtDevice *device;
IVideoDriver* driver;
ISceneManager* smgr;
ITexture* create_ITexture_from_CvCapture(CvCapture* capture);
ITexture* update_ITexture_from_CvCapture(ITexture *dest, CvCapture* capture, double time_since_last_update, double *over_flow_time);
double current_time();
int main()
{
device = createDevice( video::EDT_OPENGL, dimension2d<s32>(640, 480), 16, false, false, false, 0);
driver = device->getVideoDriver();
smgr = device->getSceneManager();
device->setWindowCaption(L"Hello World! - Irrlicht Engine Demo");
//something for 3d reference
IAnimatedMesh* mesh = smgr->getMesh("media/sydney.md2");
IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( mesh );
if (node)
{
node->setMaterialFlag(EMF_LIGHTING, false);
node->setMD2Animation ( scene::EMAT_STAND );
node->setMaterialTexture( 0, driver->getTexture("media/sydney.bmp") );
}
//our billboard
IBillboardSceneNode* our_bill_node = smgr->addBillboardSceneNode(NULL, dimension2d<f32>(25.0f, 25.0f), vector3df(-30,0,0));
our_bill_node->setMaterialFlag(video::EMF_LIGHTING, false);
//#2
IBillboardSceneNode* our_bill_node2 = smgr->addBillboardSceneNode(NULL, dimension2d<f32>(25.0f, 25.0f), vector3df(30,20,30));
our_bill_node2->setMaterialFlag(video::EMF_LIGHTING, false);
//camera stuff
ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS();
camera->setPosition(vector3df(60,0,0));
camera->setTarget(vector3df(0,0,0));
//choose your own avi's
//refer to this if needed to convert your vid to cv usable...
//mencoder in.avi -ovc raw -vf format=i420 -o out.avi
CvCapture* capture = cvCaptureFromFile("verona60avi56k.avi");
CvCapture* capture2 = cvCaptureFromFile("out.avi");
if (!capture)
printf("Could not initialize capturing1...\n");
if (!capture2)
printf("Could not initialize capturing2...\n");
//get the initial image
ITexture* CvImage = create_ITexture_from_CvCapture(capture);
ITexture* CvImage2 = create_ITexture_from_CvCapture(capture2);
our_bill_node->setMaterialTexture( 0, CvImage );
our_bill_node2->setMaterialTexture( 0, CvImage2 );
//fps stuff with a bit more precision
double last_time = current_time();
double add_on_time = 0, add_on_time2 = 0;
while(device->run())
{
driver->beginScene(true, true, SColor(255,100,101,140));
smgr->drawAll();
driver->endScene();
update_ITexture_from_CvCapture(CvImage, capture, current_time() - last_time, &add_on_time);
update_ITexture_from_CvCapture(CvImage2, capture2, current_time() - last_time, &add_on_time2);
last_time = current_time();
}
device->drop();
return 0;
}
ITexture* update_ITexture_from_CvCapture(ITexture *dest, CvCapture* capture, double time_since_last_update, double *over_flow_time)
{
//get these variables about the video
int frameH = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
int frameW = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
int fps = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
//alittle code to try and keep it all at the right speed
int frames_to_capture = (int)(fps * (time_since_last_update + *over_flow_time));
if(frames_to_capture)
{
*over_flow_time = time_since_last_update - (frames_to_capture / fps * 1.0);
}
else
{
*over_flow_time = *over_flow_time + time_since_last_update;
return dest;
}
//grab an image and potentially skip some frames
IplImage* img = 0;
for(int i=0;i<frames_to_capture; i++)
{
if(!cvGrabFrame(capture))
{
printf("Could not grab a frame\n");
return dest;
}
}
img = cvRetrieveFrame(capture);
//now put the img data into the texture data
u8* pixels = (u8*)(dest->lock());
u8* ardata = (u8*)img->imageData;
int max_pixels = frameH * frameW;
for(int i=0;i<max_pixels;i++)
{
*pixels = *ardata;
pixels++; ardata++;
*pixels = *ardata;
pixels++; ardata++;
*pixels = *ardata;
pixels++; ardata++;
pixels++;
}
dest->unlock();
return dest;
}
ITexture* create_ITexture_from_CvCapture(CvCapture* capture)
{
char unique_tex_name[50];
//for irrlicht
sprintf(unique_tex_name, "cv_image:%d", capture);
//grab an image
IplImage* img = 0;
if(!cvGrabFrame(capture))
{
printf("Could not grab a frame\n");
return 0;
}
img=cvRetrieveFrame(capture);
//get these variables about the video
int frameH = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
int frameW = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
int fps = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
//make our texture
ITexture* m_poTileTexture = driver->addTexture(core::dimension2d<s32>(frameW, frameH), unique_tex_name, video::ECF_A1R5G5B5);
// read the pixels directly into the texture
u8* pixels = (u8*)(m_poTileTexture->lock());
u8* ardata = (u8*)img->imageData;
int max_pixels = frameW * frameH;
for(int i=0;i<max_pixels;i++)
{
*pixels = *ardata;
pixels++; ardata++;
*pixels = *ardata;
pixels++; ardata++;
*pixels = *ardata;
pixels++; ardata++;
pixels++;
}
m_poTileTexture->unlock();
return m_poTileTexture;
}
//this function brings back seconds with milliseconds since it was first called
double current_time()
{
static int first_sec = 0;
static int first_msec = 0;
struct timeb new_time;
//set current time
ftime(&new_time);
//set if not set
if(!first_sec)
{
first_sec = new_time.time;
first_msec = new_time.millitm;
}
return (new_time.time - first_sec) + ((new_time.millitm - first_msec) * 0.001);
}