Example #1
0
int main()
{

    MyEventReceiver receiver;

    IrrlichtDevice *device =
        createDevice( video::EDT_OPENGL, dimension2d<u32>(1280, 800), 16,
        false, false, false, &receiver);

    if (!device)
        return 1;

    IVideoDriver* driver = device->getVideoDriver();
    ISceneManager* smgr = device->getSceneManager();
    IGUIEnvironment* guienv = device->getGUIEnvironment();

    scene::ISceneNode* o = smgr->addSphereSceneNode(20);
    //o->setMaterialFlag(video::EMF_LIGHTING, false);
    o->setPosition(core::vector3df(0,0,0));
    SMaterial &m = o->getMaterial(0);
    m.EmissiveColor = SColor(255, 255, 0, 0);


    vector3df sssPos(0, 60, 0);

    scene::ISceneNode* sss = smgr->addCubeSceneNode(30);
    sss->setMaterialFlag(video::EMF_LIGHTING, true);
    //sss->setMaterialTexture(0, driver->getTexture("wall.bmp"));
    sss->setPosition(sssPos);
    SMaterial &sssm = sss->getMaterial(0);
    sssm.EmissiveColor = SColor(100, 255, 255, 255);


    scene::ISceneNode*  hp = smgr->addSphereSceneNode(10);
    SMaterial &hpm = hp->getMaterial(0);
    hpm.EmissiveColor = SColor(255, 0, 0, 255);
    scene::ISceneNode*  hd = smgr->addSphereSceneNode(10);
    SMaterial &hdm = hd->getMaterial(0);
    hdm.EmissiveColor = SColor(255, 0, 0, 100);


    scene::ISceneNode* node[10];
    for (int i = 0; i < 10; ++i)
    {
        node[i] = smgr->addSphereSceneNode(5);
        //node[i]->setMaterialFlag(video::EMF_LIGHTING, false);
        node[i]->setVisible(false);
        SMaterial &m = node[i]->getMaterial(0);
        m.EmissiveColor = SColor(255, 255, 0, 0);
    }

    scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS();

    vector3df camPos(0,0,200);
    vector3df camshift(0,0,0);

    cam->setPosition(camPos);
    cam->setTarget(core::vector3df(0,0,0));

    u32 then = device->getTimer()->getTime();
    const f32 MOVEMENT_SPEED = 50.f;



    irr::video::S3DVertex m_cPlaneVertices[4];
    irr::u16 m_iPlaneIndices[6];

    m_cPlaneVertices[0] = irr::video::S3DVertex(-100.0f, -100.0f, -100.0f,1,1,0, irr::video::SColor(255,255,255,255), 0.0f, 0.0f);
    m_cPlaneVertices[1] = irr::video::S3DVertex(-100.0f,  100.0f, -100.0f,1,1,0, irr::video::SColor(255,255,255,255), 0.0f, 1.0f);
    m_cPlaneVertices[2] = irr::video::S3DVertex( 100.0f,  100.0f, -100.0f,1,1,0, irr::video::SColor(255,255,255,255), 1.0f, 1.0f);
    m_cPlaneVertices[3] = irr::video::S3DVertex( 100.0f, -100.0f, -100.0f,1,1,0, irr::video::SColor(255,255,255,255), 1.0f, 0.0f);

    m_iPlaneIndices[0] = 0;
    m_iPlaneIndices[1] = 2;
    m_iPlaneIndices[2] = 1;
    m_iPlaneIndices[3] = 0;
    m_iPlaneIndices[4] = 3;
    m_iPlaneIndices[5] = 2;


    SMaterial m_cRenderMaterial;
    m_cRenderMaterial.Wireframe = false;
    m_cRenderMaterial.Lighting = false;
    m_cRenderMaterial.TextureLayer[0].TextureWrapU = irr::video::ETC_CLAMP;
    m_cRenderMaterial.TextureLayer[0].TextureWrapV = irr::video::ETC_CLAMP;
    
    ITexture      *m_pRenderTexture = 0;

    CvCapture *capture;
    IplImage *frame;
    char AviFileName[]="Accel World.mp4";
    capture = cvCaptureFromAVI(AviFileName);

    if (driver->queryFeature(irr::video::EVDF_RENDER_TO_TARGET))
    {
        m_pRenderTexture = driver->addRenderTargetTexture(irr::core::dimension2d<irr::u32>((irr::u32)(720), (irr::u32)(480)));
        m_cRenderMaterial.setTexture(0, m_pRenderTexture);
    }

//     m_pRenderTexture = driver->getTexture("wall.bmp");
//     m_cRenderMaterial.setTexture(0, m_pRenderTexture);

    while(device->run())
    {
        const u32 now = device->getTimer()->getTime();
        const f32 frameDeltaTime = (f32)(now - then) / 1000.f; // Time in seconds
        then = now;

        if(receiver.IsKeyDown(irr::KEY_KEY_W))
            camshift.Z -= MOVEMENT_SPEED * frameDeltaTime;
        else if(receiver.IsKeyDown(irr::KEY_KEY_S))
            camshift.Z += MOVEMENT_SPEED * frameDeltaTime;

        if(receiver.IsKeyDown(irr::KEY_KEY_A))
            camshift.X -= MOVEMENT_SPEED * frameDeltaTime;
        else if(receiver.IsKeyDown(irr::KEY_KEY_D))
            camshift.X += MOVEMENT_SPEED * frameDeltaTime;

        if(receiver.IsKeyDown(irr::KEY_KEY_X))
            camshift.Y -= MOVEMENT_SPEED * frameDeltaTime;
        else if(receiver.IsKeyDown(irr::KEY_SPACE))
            camshift.Y += MOVEMENT_SPEED * frameDeltaTime;

        cam->setPosition(camPos + camshift);


        driver->beginScene(true, true, SColor(255,0,0,0));




        driver->setRenderTarget(m_pRenderTexture, true, true, irr::video::SColor(0,0,0,0));
        
        if(cvGrabFrame(capture))
        {
            frame=cvRetrieveFrame(capture);

            void* pBits = m_pRenderTexture->lock();
            u32  Pitch = m_pRenderTexture->getPitch();  

            int wmin= Pitch;
//             for(int h=0; h< 100; h++) 
//                 memcpy((char*)pBits+((h)*wmin),(char*)frame->imageDataOrigin + h * wmin, wmin);

            char* tmp = new char[frame->imageSize + 720 * 480];
            for (int i = 0; i < 480; ++i)
            {
                for (int j = 0; j < 720; ++j)
                {
                    tmp[(i * 720 + j) * 4] = frame->imageDataOrigin[(i * 720 + j) * 3];
                    tmp[(i * 720 + j) * 4 + 1] = frame->imageDataOrigin[(i * 720 + j) * 3 + 1];
                    tmp[(i * 720 + j) * 4 + 2] = frame->imageDataOrigin[(i * 720 + j) * 3 + 2];
                    tmp[(i * 720 + j) * 4 + 3] = 255;
                }
            }

            memcpy(pBits,tmp, frame->imageSize + 720 * 480);

            delete []tmp;

            m_pRenderTexture->unlock();

        }

        driver->setRenderTarget(0, false, false, irr::video::SColor(0,100,100,100));

        //driver->setTransform(video::ETS_VIEW, core::matrix4());
        driver->setTransform(video::ETS_WORLD, core::matrix4());
        //driver->setTransform(video::ETS_PROJECTION, core::matrix4());

        driver->setMaterial(m_cRenderMaterial);
        driver->drawIndexedTriangleList(m_cPlaneVertices, 4, m_iPlaneIndices, 2);

        



        smgr->drawAll();

        driver->endScene();
    }

    //controller.removeListener(listener);
    device->drop();

    return 0;
}
Example #2
0
//! @brief render big software image of any size using either screen to render or offscreen texture ( can flicker )
bool renderToImage( IrrlichtDevice* device, IImage* dst, s32 nSamples, const SColor& clearColor, bool renderGUI, bool debugLog)
{
	// print call params
	if (debugLog)
		printf(	"renderToImage( nSamples=%i, clearColor(%i,%i,%i,%i)\n", nSamples,
			clearColor.getAlpha(), clearColor.getRed(), clearColor.getGreen(), clearColor.getBlue() );

	// abort
    if (!device)
	{
		printf("No Irrlicht-Device found.\n");
        return false;
	}

	// abort
    if (!dst)
	{
		printf("No destination image found.\n");
        return false;
	}

	// local pointers
	IVideoDriver* driver = device->getVideoDriver();
	gui::IGUIEnvironment* guienv = device->getGUIEnvironment();
	scene::ISceneManager* smgr = device->getSceneManager();
	scene::ICameraSceneNode* camera = smgr->getActiveCamera();

	// abort
	if (!camera)
	{
		printf("No active camera found.\n");
		return false;
	}

	//! decompose camera's projection-matrix in d3d semantics

	core::matrix4 projMat = camera->getProjectionMatrix();

	bool IsOrthogonal = true;

	if ( core::equals( projMat(3,3), 0.f ) )
		IsOrthogonal = false;

	if ( !core::equals( projMat(2,3), 0.f ) )
		IsOrthogonal = false;

    f32 Left;
    f32 Right;
    f32 Bottom;
    f32 Top;
    f32 Near;
    f32 Far;

	if (IsOrthogonal)
	{
		Near = -projMat(3,2)/projMat(2,2);
		Far = -(projMat(3,2)-1.f)/projMat(2,2);
		Left = -(projMat(3,0)+1.f)/projMat(0,0);
		Right = -(projMat(3,0)-1.f)/projMat(0,0);
		Top = -(projMat(3,1)-1.f)/projMat(1,1);
		Bottom = -(projMat(3,1)+1.f)/projMat(1,1);
	}
	else
	{
		Near = -projMat(3,2)/projMat(2,2);
		Far = -projMat(3,2)/(projMat(2,2)-1.f);
		Left = -Near*(projMat(2,0)+1.f)/projMat(0,0);
		Right = -Near*(projMat(2,0)-1.f)/projMat(0,0);
		Top = -Near*(projMat(2,1)-1.f)/projMat(1,1);
		Bottom = -Near*(projMat(2,1)+1.f)/projMat(1,1);
	}
	Near = camera->getNearValue();	// take the values directly from Camera
	Far = camera->getFarValue();	// due to f32 rounding errors

	//! ----------------------------------------------------------------------
	//! calculate Border / get max thickness used by all registered materials
	//! ----------------------------------------------------------------------

	s32 Border = 0;
	f32 thickness = 0.0f;

    const core::list<scene::ISceneNode*>& children = smgr->getRootSceneNode()->getChildren();
    core::list<scene::ISceneNode*>::ConstIterator it = children.begin();

    while (it != children.end())
	{
		scene::ISceneNode* node = (*it);
		if (node)
		{
			u32 matCount = node->getMaterialCount();
			for (u32 m = 0; m < matCount; ++m)
			{
				if (thickness < node->getMaterial(m).Thickness)
					thickness = node->getMaterial(m).Thickness;
			}
		}
		it++;
	}

	Border = core::ceil32( thickness );

	//! ------------------------------------------------------------------------------------------
	//! choose render-mode: offscreen or onscreen depending on AA, nSamples and RTT capabilities
	//! ------------------------------------------------------------------------------------------

	//! @var nSamples - AntiAliasing depth > 1 make bigger rtts or downscale render-result by factor nSamples while having filter-methods enabled
	//! the framebuffer will always be downscaled by fast software bilinear filtering using colorkey/transparency to blend better into final image
	//! hardware-scaling: bilinear, trilinear or anisotropic texture-filtering available with irrlicht-engine
	//! software scaling: nearest, bilinear, bicubic downscaling available:
	//!  				  bilinear has best compromise for downscaling ( there is much more information-loss due to resize than interpolation)
	//! default: 1 (<2) - no AA/downscaling done

	//! @var clearColor - argb32 color, the final image will filled with
	//! before writing into it and be used as colorkey for AA/software bilinear downscaling operation

	//! @var DoOffscreen - default=false, onscreen (framebuffer)
	//! false -	onscreen-rendering using framebuffer/display.
	//! 		doublebuffer is possible, but will not prevent the showing of each rendered tile-texture
	//! true - 	offscreen-rendering using render-target-textures

	bool DoOffscreen = false;

	//! ----------------------------------------------------------------
	//! collect video-driver infos
	//! ----------------------------------------------------------------

	const core::dimension2du ScreenSize = driver->getScreenSize();
	const ECOLOR_FORMAT ScreenFormat = driver->getColorFormat();
	const u32 ScreenBits = IImage::getBitsPerPixelFromFormat( ScreenFormat );
    const io::IAttributes& info = driver->getDriverAttributes();
    const core::dimension2du MaxRTTSize = driver->getMaxTextureSize();
    const u32 MaxAA = info.getAttributeAsInt( "AntiAlias" );
    const u32 MaxAF = info.getAttributeAsInt( "MaxAnisotropy" );
    const bool HasNPOT = driver->queryFeature( EVDF_TEXTURE_NPOT );
    const bool HasNSQR = driver->queryFeature( EVDF_TEXTURE_NSQUARE );
	const bool HasRTT = driver->queryFeature( EVDF_RENDER_TO_TARGET);
	const bool HasMTT = driver->queryFeature( EVDF_MULTITEXTURE);
	const bool HasMRT = driver->queryFeature( EVDF_MULTIPLE_RENDER_TARGETS);
	const bool HasATC = driver->queryFeature( EVDF_ALPHA_TO_COVERAGE);
	const bool HasBTF = driver->queryFeature( EVDF_BILINEAR_FILTER);
	const bool HasCMK = driver->queryFeature( EVDF_COLOR_MASK);
	const bool HasMMP = driver->queryFeature( EVDF_MIP_MAP);
	const bool HasMMA = driver->queryFeature( EVDF_MIP_MAP_AUTO_UPDATE);
	const bool HasOCC = driver->queryFeature( EVDF_OCCLUSION_QUERY);
	const bool HasPOF = driver->queryFeature( EVDF_POLYGON_OFFSET);

	if (debugLog)
	{
		printf("ScreenSize = %i x %i x %i\n", ScreenSize.Width, ScreenSize.Height, ScreenBits);
		printf("MaxRTTSize = %i x %i\n", MaxRTTSize.Width, MaxRTTSize.Height);
		printf("MaxAA = %i\n", MaxAA);
		printf("MaxAF = %i\n", MaxAF);
		printf("HasNPOT = %s\n", HasNPOT?"true":"false");
		printf("HasNSQR = %s\n", HasNSQR?"true":"false");
		printf("HasRTT = %s\n", HasRTT?"true":"false");
		printf("HasMTT = %s\n", HasMTT?"true":"false");
		printf("HasMRT = %s\n", HasMRT?"true":"false");
		printf("HasATC = %s\n", HasATC?"true":"false");
		printf("HasBTF = %s\n", HasBTF?"true":"false");
		printf("HasCMK = %s\n", HasCMK?"true":"false");
		printf("HasMMP = %s\n", HasMMP?"true":"false");
		printf("HasMMA = %s\n", HasMMA?"true":"false");
		printf("HasOCC = %s\n", HasOCC?"true":"false");
		printf("HasPOF = %s\n", HasPOF?"true":"false");
	}

    s32 RTTWidth = ScreenSize.Width;				// equals the actual rtt size before down scaling factor nSamples AA and writing to final Image
    s32 RTTHeight = ScreenSize.Height;				// the render-target is always a texture (offscreen) or the framebuffer (onscreen)
    s32 RTTWidthNB = RTTWidth - 2*Border;			// the border equals the overlapping during rendering due to material-thickness > 0
    s32 RTTHeightNB = RTTHeight - 2*Border;			// the area that gets written to unique places, while the border regions can overlapp ( same pos, but writing/adding different image-content )

	// so the position increment for the final writing is always RTTWidthNB or RTTHeightNB

    const s32 ImageWidth = (s32)dst->getDimension().Width;		// width of the final image
    const s32 ImageHeight = (s32)dst->getDimension().Height;	// height of the final image
    const ECOLOR_FORMAT ImageFormat = dst->getColorFormat();			// color-format of the final image, i.e. ECF_A8R8G8B8, ECF_R8G8B8, ECF_R16 for heightmaps ( bilinear, anisotropic )
	const s32 CountX = core::ceil32( (f32)ImageWidth / (f32)RTTWidthNB );
	const s32 CountY = core::ceil32( (f32)ImageHeight / (f32)RTTHeightNB );

	//! ------------------------------------------------------------------------------------------
	//! start render loop
	//! ------------------------------------------------------------------------------------------

    s32 IndexX = 0;
    s32 IndexY = 0;
	s32 dstX = -Border;
	s32 dstY = -Border;

	for ( IndexY = 0; IndexY < CountY; ++IndexY)
	{
		// reset row
		dstX = -Border;

		for ( IndexX = 0; IndexX < CountX; ++IndexX)
		{
			const f32 fLeft = Left + (Right - Left) * (f32)( IndexX * RTTWidthNB - Border )/(f32)ImageWidth;
			const f32 fRight = fLeft + (Right - Left) * (f32)RTTWidth / (f32)ImageWidth;
			const f32 fTop = Top - (Top - Bottom) * (f32)( IndexY * RTTHeightNB - Border )/(f32)ImageHeight;
			const f32 fBottom = fTop - (Top - Bottom) * (f32)RTTHeight / (f32)ImageHeight;
			const f32 fNear = Near;
			const f32 fFar = Far;

			//! ------------------------------------------------------------------------------------------
			//! build and set current projection-matrix
			//! ------------------------------------------------------------------------------------------

			core::matrix4 tmpProj = core::IdentityMatrix;
			if (IsOrthogonal)
			{
				tmpProj(0,0) = 2.f / (fRight - fLeft);
				tmpProj(1,1) = 2.f / (fTop - fBottom);
				tmpProj(2,2) = 1.f / (fFar - fNear);
				tmpProj(3,3) = 1.f;
				tmpProj(3,0) = (fLeft + fRight) / (fLeft - fRight);
				tmpProj(3,1) = (fTop + fBottom) / (fBottom - fTop);
				tmpProj(3,2) = fNear / (fNear - fFar);
			}
			else
			{
				tmpProj(0,0) = 2.f*fNear / (fRight - fLeft);
				tmpProj(1,1) = 2.f*fNear / (fTop - fBottom);
				tmpProj(2,0) = (fLeft + fRight) / (fLeft - fRight);
				tmpProj(2,1) = (fTop + fBottom) / (fBottom - fTop);
				tmpProj(2,2) = fFar / (fFar - fNear);
				tmpProj(2,3) = 1.f;
				tmpProj(3,2) = fNear*fFar / (fNear - fFar);
				tmpProj(3,3) = 0.f;
			}
			camera->setProjectionMatrix(tmpProj);

			//! ------------------------------------------------------------------------------------------
			//! now render all to current render-target
			//! ------------------------------------------------------------------------------------------

			driver->beginScene( true, true, clearColor ); // SColor(255,200,200,255)

				smgr->drawAll();
				if (renderGUI)
					guienv->drawAll();

			driver->endScene();

			//! ------------------------------------------------------------------------------------------
			//! write current render-target to final image
			//! ------------------------------------------------------------------------------------------

			IImage* src = driver->createScreenShot( ImageFormat, ERT_FRAME_BUFFER);
			if (src)
			{
				s32 x2 = src->getDimension().Width;
				s32 y2 = src->getDimension().Height;

				blitImageToImage( dst, core::position2di(dstX, dstY), src, core::recti(Border, Border, x2-Border, y2-Border), debugLog );

				src->drop();
			}
			dstX += RTTWidthNB;
		}
		dstY += RTTHeightNB;
	}

	//! ------------------------------------------------------------------------------------------
	//! reset camera's projection-matrix
	//! ------------------------------------------------------------------------------------------

	camera->setProjectionMatrix( projMat, IsOrthogonal);
    return true;
}