// -----------------------------------------------------------------------------
video::ITexture* IconButtonWidget::getDeactivatedTexture(video::ITexture* texture)
{
    SColor c;
    u32 g;

    video::IVideoDriver* driver = irr_driver->getVideoDriver();
    video::IImage* image = driver->createImageFromData (texture->getColorFormat(),
        texture->getSize(), texture->lock(), false);
    texture->unlock();

    //Turn the image into grayscale
    for (u32 x = 0; x < image->getDimension().Width; x++)
    {
        for (u32 y = 0; y < image->getDimension().Height; y++)
        {
            c = image->getPixel(x, y);
            g = ((c.getRed() + c.getGreen() + c.getBlue()) / 3);
            c.set(std::max (0, (int)c.getAlpha() - 120), g, g, g);
            image->setPixel(x, y, c);
        }
    }

    texture = driver->addTexture(texture->getName().getPath() + "_disabled", image);
    texture->grab();

    return texture;
}
Exemplo n.º 2
0
//! get a filtered pixel
inline SColor CImage::getPixelBox( s32 x, s32 y, s32 fx, s32 fy, s32 bias ) const
{
	SColor c;
	s32 a = 0, r = 0, g = 0, b = 0;

	for ( s32 dx = 0; dx != fx; ++dx )
	{
		for ( s32 dy = 0; dy != fy; ++dy )
		{
			c = getPixel(	core::s32_min ( x + dx, Size.Width - 1 ) ,
							core::s32_min ( y + dy, Size.Height - 1 )
						);

			a += c.getAlpha();
			r += c.getRed();
			g += c.getGreen();
			b += c.getBlue();
		}

	}

	s32 sdiv = s32_log2_s32(fx * fy);

	a = core::s32_clamp( ( a >> sdiv ) + bias, 0, 255 );
	r = core::s32_clamp( ( r >> sdiv ) + bias, 0, 255 );
	g = core::s32_clamp( ( g >> sdiv ) + bias, 0, 255 );
	b = core::s32_clamp( ( b >> sdiv ) + bias, 0, 255 );

	c.set( a, r, g, b );
	return c;
}
Exemplo n.º 3
0
		//! Constructs a color from 32 bit Color.
		SColorf::SColorf(SColor c)
		{
			const f32 inv = 1.0f / 255.0f;
			Red = c.getRed() * inv;
			Green = c.getGreen() * inv;
			Blue = c.getBlue() * inv;
			Alpha = c.getAlpha() * inv;
		}
Exemplo n.º 4
0
// ----------------------------------------------------------------------------
void Terrain::pixelSoftBrush(u8* img, int ix, SColor col, double e)
{
    if (e > 0)
    {
        img[ix + 3] = (u8) std::max(std::min(img[ix + 3] + e * col.getAlpha()
            - e * col.getRed() - e * col.getGreen() - e * col.getBlue(), 255.0), 0.0);
        img[ix + 2] = (u8) std::max(std::min(img[ix + 2] + e * col.getRed()
            - e * col.getAlpha() - e * col.getGreen() - e * col.getBlue(), 255.0), 0.0);
        img[ix + 1] = (u8) std::max(std::min(img[ix + 1] + e * col.getGreen()
            - e * col.getRed() - e * col.getAlpha() - e * col.getBlue(), 255.0), 0.0);
        img[ix + 0] = (u8) std::max(std::min(img[ix + 0] + e * col.getBlue()
            - e * col.getRed() - e * col.getGreen() - e * col.getAlpha(), 255.0), 0.0);
    }
    else
    {
        img[ix + 3] = (u8) std::max(img[ix + 3] + e * col.getAlpha(), 0.0);
        img[ix + 2] = (u8) std::max(img[ix + 2] + e * col.getRed(), 0.0);
        img[ix + 1] = (u8) std::max(img[ix + 1] + e * col.getGreen(), 0.0);
        img[ix + 0] = (u8) std::max(img[ix + 0] + e * col.getBlue(), 0.0);
    }

} // vertexSoftBrush
Exemplo n.º 5
0
void CD3D9Texture::copy16BitMipMap(char* src, char* tgt,
				   s32 width, s32 height,
				   s32 pitchsrc, s32 pitchtgt) const
{
	for (s32 y=0; y<height; ++y)
	{
		for (s32 x=0; x<width; ++x)
		{
			u32 a=0, r=0, g=0, b=0;

			for (s32 dy=0; dy<2; ++dy)
			{
				const s32 tgy = (y*2)+dy;
				for (s32 dx=0; dx<2; ++dx)
				{
					const s32 tgx = (x*2)+dx;

					SColor c;
					if (ColorFormat == ECF_A1R5G5B5)
						c = A1R5G5B5toA8R8G8B8(*(u16*)(&src[(tgx*2)+(tgy*pitchsrc)]));
					else
						c = R5G6B5toA8R8G8B8(*(u16*)(&src[(tgx*2)+(tgy*pitchsrc)]));

					a += c.getAlpha();
					r += c.getRed();
					g += c.getGreen();
					b += c.getBlue();
				}
			}

			a /= 4;
			r /= 4;
			g /= 4;
			b /= 4;

			u16 c;
			if (ColorFormat == ECF_A1R5G5B5)
				c = RGBA16(r,g,b,a);
			else
				c = A8R8G8B8toR5G6B5(SColor(a,r,g,b).color);
			*(u16*)(&tgt[(x*2)+(y*pitchtgt)]) = c;
		}
	}
}
// -----------------------------------------------------------------------------
video::ITexture* IconButtonWidget::getDeactivatedTexture(video::ITexture* texture)
{
#if !defined(SERVER_ONLY) && !defined(USE_GLES2)
    STKTexture* stk_tex = static_cast<STKTexture*>(texture);
    // Compressed texture can't be turned into greyscale
    if (stk_tex->isMeshTexture() && CVS->isTextureCompressionEnabled())
        return stk_tex;

    std::string name = stk_tex->getName().getPtr();
    name += "_disabled";
    STKTexManager* stkm = STKTexManager::getInstance();
    STKTexture* disabled_stk_tex = static_cast<STKTexture*>(stkm->getTexture
        (name, NULL/*tc*/, false /*no_upload*/, false/*create_if_unfound*/));
    if (disabled_stk_tex == NULL)
    {
        SColor c;
        u32 g;

        video::IVideoDriver* driver = irr_driver->getVideoDriver();
        video::IImage* image = driver->createImageFromData
            (video::ECF_A8R8G8B8, stk_tex->getSize(), stk_tex->lock(),
            stk_tex->getTextureImage() == NULL/*ownForeignMemory*/);
        texture->unlock();

        //Turn the image into grayscale
        for (u32 x = 0; x < image->getDimension().Width; x++)
        {
            for (u32 y = 0; y < image->getDimension().Height; y++)
            {
                c = image->getPixel(x, y);
                g = ((c.getRed() + c.getGreen() + c.getBlue()) / 3);
                c.set(std::max (0, (int)c.getAlpha() - 120), g, g, g);
                image->setPixel(x, y, c);
            }
        }
        return stkm->addTexture(new STKTexture(image, name));
    }
    return disabled_stk_tex;
#else
    return texture;
#endif   // !SERVER_ONLY
}
Exemplo n.º 7
0
void CD3D8Texture::copy32BitMipMap(char* src, char* tgt,
				   s32 width, s32 height,
				   s32 pitchsrc, s32 pitchtgt) const
{
	SColor c;

	for (int x=0; x<width; ++x)
	{
		for (int y=0; y<height; ++y)
		{
			s32 a=0, r=0, g=0, b=0;

			for (int dx=0; dx<2; ++dx)
			{
				for (int dy=0; dy<2; ++dy)
				{
					int tgx = (x*2)+dx;
					int tgy = (y*2)+dy;

					c = *(u32*)((void*)&src[(tgx<<2)+(tgy*pitchsrc)]);

					a += c.getAlpha();
					r += c.getRed();
					g += c.getGreen();
					b += c.getBlue();
				}
			}

			a >>= 2;
			r >>= 2;
			g >>= 2;
			b >>= 2;

			c = ((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff);
			*(u32*)((void*)&tgt[(x*4)+(y*pitchtgt)]) = c.color;
		}
	}
}
// -----------------------------------------------------------------------------
video::ITexture* IconButtonWidget::getDeactivatedTexture(video::ITexture* texture)
{
#ifdef DO_NOT_USE_IT_CAUSES_BUG_1780_FONT_CORRUPTION
    video::ITexture* t;

    std::string name = texture->getName().getPath().c_str();
    name += "_disabled";
    t = irr_driver->getTexture(name, /*premul*/false, /*prediv*/false,
                                     /*compain_if_not_found*/false);
    if (t == NULL)
    {
        SColor c;
        u32 g;

        video::IVideoDriver* driver = irr_driver->getVideoDriver();
        std::unique_ptr<video::IImage> image (driver->createImageFromData (texture->getColorFormat(),
            texture->getSize(), texture->lock(), false));
        texture->unlock();

        //Turn the image into grayscale
        for (u32 x = 0; x < image->getDimension().Width; x++)
        {
            for (u32 y = 0; y < image->getDimension().Height; y++)
            {
                c = image->getPixel(x, y);
                g = ((c.getRed() + c.getGreen() + c.getBlue()) / 3);
                c.set(std::max (0, (int)c.getAlpha() - 120), g, g, g);
                image->setPixel(x, y, c);
            }
        }

        t = driver->addTexture(name.c_str(), image.get ());
    }

    return t;
#endif
    return texture;
}
Exemplo n.º 9
0
void CD3D9Texture::copy32BitMipMap(char* src, char* tgt,
				   s32 width, s32 height,
				   s32 pitchsrc, s32 pitchtgt) const
{
	for (s32 y=0; y<height; ++y)
	{
		for (s32 x=0; x<width; ++x)
		{
			u32 a=0, r=0, g=0, b=0;
			SColor c;

			for (s32 dy=0; dy<2; ++dy)
			{
				const s32 tgy = (y*2)+dy;
				for (s32 dx=0; dx<2; ++dx)
				{
					const s32 tgx = (x*2)+dx;

					c = *(u32*)(&src[(tgx*4)+(tgy*pitchsrc)]);

					a += c.getAlpha();
					r += c.getRed();
					g += c.getGreen();
					b += c.getBlue();
				}
			}

			a /= 4;
			r /= 4;
			g /= 4;
			b /= 4;

			c.set(a, r, g, b);
			*(u32*)(&tgt[(x*4)+(y*pitchtgt)]) = c.color;
		}
	}
}
Exemplo n.º 10
0
int main()
{
    // ask user for driver
    video::E_DRIVER_TYPE driverType=driverChoiceConsole();
    if (driverType==video::EDT_COUNT)
        return 1;

    // create device and exit if creation failed

    Device = createDevice(driverType, core::dimension2d<u32>(640, 480));
    if(Device == NULL)
        return 1;

    IVideoDriver *Driver = Device->getVideoDriver();
    IGUIEnvironment* env = Device->getGUIEnvironment();
    ISceneManager *Scene = Device->getSceneManager();

    Scene->addCameraSceneNode(0, vector3df(0,10,-40), vector3df(0,0,0));

    MyEventReceiver receiver;
    Device->setEventReceiver(&receiver);

    // Load fonts
    fonts[0] = env->getFont(FONTPATH1, SIZE_FONT_NORMAL);
    fonts[1] = env->getFont(FONTPATH1, SIZE_FONT_BIG);
    fonts[2] = env->getFont(FONTPATH2, SIZE_FONT_NORMAL);
    fonts[3] = env->getFont(FONTPATH2, SIZE_FONT_BIG);
    fonts[4] = env->getFont(FONTPATH3, SIZE_FONT_NORMAL);
    fonts[5] = env->getFont(FONTPATH3, SIZE_FONT_BIG);

    for( int i = 0; i < 6; ++i ) {
        fonts[i]->setBatchLoadSize(1);
        fonts[i]->setMaxPageTextureSize( dimension2du(512, 512) );
    }

    font = fonts[0];
    font2 = fonts[1];

    skin = env->getSkin();
    skin->setFont(font);

    txtTrans = env->addStaticText(L"Transparency:", rect<s32>(50,20,250,40), true);
    IGUIScrollBar* scrollbar = env->addScrollBar(true, rect<s32>(50, 45, 250, 60), 0, 104);
    scrollbar->setMax(255);
    SColor col = env->getSkin()->getColor((EGUI_DEFAULT_COLOR)0);
    scrollbar->setPos(col.getAlpha());

    txtLog = env->addStaticText(L"Logging ListBox:", rect<s32>(50,80,250,100), true);
    listbox = env->addListBox(rect<s32>(50, 110, 250, 180));

    btnQuit = env->addButton(rect<s32>(10,210,100,240), 0, 101, L"Quit");
    btnNew = env->addButton(rect<s32>(10,250,100,290), 0, 102, L"New Window");
    btnFile = env->addButton(rect<s32>(10,300,100,340), 0, 103, L"Open File");

    edtName = env->addEditBox(L"",rect<s32>(300,60,580,80));
    edtName->setMax(40);
    edtMemo = env->addEditBox(L"",rect<s32>(300,100,580,450));
    edtMemo->setMultiLine(true);
    edtMemo->setTextAlignment(EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);

    lstLang = env->addListBox(rect<s32>(10, 400, 250, 470),0,120);
    lstLang->addItem(L"Arial");
    lstLang->addItem(L"Times Roman");
    lstLang->addItem(L"MS-Gothic(Japanese)");
    lstLang->setSelected(0);

    int lastFPS = -1;

    while(Device->run())
    {
        Driver->beginScene(true, true, SColor(0,64,64,128));

        Scene->drawAll();
        env->drawAll();

        if (!lang){
            font2->draw(L"Hello TrueType",rect<s32>(250,20,640,100),SColor(255,255,64,64),true);
        } else {
            //font2->draw(jtxtHello,rect<s32>(250,20,640,100),SColor(255,255,64,64),true);
            font2->draw(zhtwHello,rect<s32>(100,100,640,100),SColor(255,255,64,64),false);
        }

        Driver->endScene();

        int fps = Driver->getFPS();
        if (lastFPS != fps)
        {
            wchar_t tmp[1024];
            swprintf(tmp, L"Irrlicht TrueType Demo (fps:%d)", fps);
            Device->setWindowCaption(tmp);
            lastFPS = fps;
        }

    }

    Device->drop();
    return 0;
}
Exemplo n.º 11
0
		// Methods for Software drivers, non-virtual and not necessary to copy into other image classes
		//! draws a rectangle
		void CImage::drawRectangle(const core::rect<s32>& rect,
				const SColor &color)
		{
			Blit(color.getAlpha() == 0xFF ? BLITTER_COLOR : BLITTER_COLOR_ALPHA,
					this, 0, &rect.UpperLeftCorner, 0, &rect, color.color);
		}
Exemplo n.º 12
0
void SerializeOutSColor(ostream& os, SColor& color)
{
	os << color.getAlpha()<< endl << color.getRed() << endl << color.getGreen() << endl << color.getBlue() << endl;
}
Exemplo n.º 13
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;
}