示例#1
0
// Pure 32 bit float precision brute force pixel conversion; for comparison
void naiveBulkPixelConversion(const PixelBox &src, const PixelBox &dst)
{
    uint8 *srcptr = static_cast<uint8*>(src.data);
    uint8 *dstptr = static_cast<uint8*>(dst.data);
    unsigned int srcPixelSize = PixelUtil::getNumElemBytes(src.format);
    unsigned int dstPixelSize = PixelUtil::getNumElemBytes(dst.format);

    // Calculate pitches+skips in bytes
    int srcRowSkipBytes = src.getRowSkip()*srcPixelSize;
    int srcSliceSkipBytes = src.getSliceSkip()*srcPixelSize;

    int dstRowSkipBytes = dst.getRowSkip()*dstPixelSize;
    int dstSliceSkipBytes = dst.getSliceSkip()*dstPixelSize;

	// The brute force fallback
	float r,g,b,a;
	for(size_t z=src.front; z<src.back; z++)
	{
		for(size_t y=src.top; y<src.bottom; y++)
		{
			for(size_t x=src.left; x<src.right; x++)
			{
				PixelUtil::unpackColour(&r, &g, &b, &a, src.format, srcptr);
				PixelUtil::packColour(r, g, b, a, dst.format, dstptr);
				srcptr += srcPixelSize;
				dstptr += dstPixelSize;
			}
			srcptr += srcRowSkipBytes;
			dstptr += dstRowSkipBytes;
		}
		srcptr += srcSliceSkipBytes;
		dstptr += dstSliceSkipBytes;
	}

}
	void SDLWindow::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer)
	{
		if ((dst.left < 0) || (dst.right > mWidth) ||
			(dst.top < 0) || (dst.bottom > mHeight) ||
			(dst.front != 0) || (dst.back != 1))
		{
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
						"Invalid box.",
						"SDLWindow::copyContentsToMemory" );
		}
	
		if (buffer == FB_AUTO)
		{
			buffer = mIsFullScreen? FB_FRONT : FB_BACK;
		}
	
		GLenum format = Ogre::GLPixelUtil::getGLOriginFormat(dst.format);
		GLenum type = Ogre::GLPixelUtil::getGLOriginDataType(dst.format);
	
		if ((format == GL_NONE) || (type == 0))
		{
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
						"Unsupported format.",
						"SDLWindow::copyContentsToMemory" );
		}
	
		// Switch context if different from current one
		RenderSystem* rsys = Root::getSingleton().getRenderSystem();
		rsys->_setViewport(this->getViewport(0));
	
		// Must change the packing to ensure no overruns!
		glPixelStorei(GL_PACK_ALIGNMENT, 1);
	
		glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK);
		glReadPixels((GLint)dst.left, (GLint)dst.top,
					 (GLsizei)dst.getWidth(), (GLsizei)dst.getHeight(),
					 format, type, dst.data);
	
		// restore default alignment
		glPixelStorei(GL_PACK_ALIGNMENT, 4);
	
		//vertical flip
		{
			size_t rowSpan = dst.getWidth() * PixelUtil::getNumElemBytes(dst.format);
			size_t height = dst.getHeight();
			uchar *tmpData = new uchar[rowSpan * height];
			uchar *srcRow = (uchar *)dst.data, *tmpRow = tmpData + (height - 1) * rowSpan;
	
			while (tmpRow >= tmpData)
			{
				memcpy(tmpRow, srcRow, rowSpan);
				srcRow += rowSpan;
				tmpRow -= rowSpan;
			}
			memcpy(dst.data, tmpData, rowSpan * height);
	
			delete [] tmpData;
		}
	}
示例#3
0
//-------------------------------------------------------------------------------------------------//
void OSXWindow::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer)
{
	if ((dst.left < 0) || (dst.right > mWidth) ||
		(dst.top < 0) || (dst.bottom > mHeight) ||
		(dst.front != 0) || (dst.back != 1))
	{
		OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
					"Invalid box.",
					"OSXWindow::copyContentsToMemory" );
	}

	if (buffer == FB_AUTO)
	{
		buffer = mIsFullScreen? FB_FRONT : FB_BACK;
	}

	GLenum format = Ogre::GLPixelUtil::getGLOriginFormat(dst.format);
	GLenum type = Ogre::GLPixelUtil::getGLOriginDataType(dst.format);

	if ((format == GL_NONE) || (type == 0))
	{
		OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
					"Unsupported format.",
					"OSXWindow::copyContentsToMemory" );
	}

	if((dst.getWidth()*Ogre::PixelUtil::getNumElemBytes(dst.format)) & 3)
	{
		// Standard alignment of 4 is not right
		glPixelStorei(GL_PACK_ALIGNMENT, 1);
	}
	
	glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK);
	glReadPixels((GLint)dst.left, (GLint)dst.top,
				 (GLsizei)dst.getWidth(), (GLsizei)dst.getHeight(),
				 format, type, dst.data);

	glPixelStorei(GL_PACK_ALIGNMENT, 4);
	
	//vertical flip
	{
		size_t rowSpan = dst.getWidth() * PixelUtil::getNumElemBytes(dst.format);
		size_t height = dst.getHeight();
		uchar *tmpData = new uchar[rowSpan * height];
		uchar *srcRow = (uchar *)dst.data, *tmpRow = tmpData + (height - 1) * rowSpan;

		while (tmpRow >= tmpData)
		{
			memcpy(tmpRow, srcRow, rowSpan);
			srcRow += rowSpan;
			tmpRow -= rowSpan;
		}
		memcpy(dst.data, tmpData, rowSpan * height);

		delete [] tmpData;
	}
}
    void GLES2HardwarePixelBuffer::blitFromMemory(const PixelBox &src, const Image::Box &dstBox)
    {
        if (!mBuffer.contains(dstBox))
        {
            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
                        "Destination box out of range",
                        "GLES2HardwarePixelBuffer::blitFromMemory");
        }

        PixelBox scaled;

        if (src.getWidth() != dstBox.getWidth() ||
            src.getHeight() != dstBox.getHeight() ||
            src.getDepth() != dstBox.getDepth())
        {
            // Scale to destination size.
            // This also does pixel format conversion if needed
            allocateBuffer();
            scaled = mBuffer.getSubVolume(dstBox);
            Image::scale(src, scaled, Image::FILTER_BILINEAR);
        }
#if OGRE_PLATFORM != OGRE_PLATFORM_APPLE_IOS
        else if ((src.format != mFormat) ||                 
                 ((GLES2PixelUtil::getGLOriginFormat(src.format) == 0) && (src.format != PF_R8G8B8)))
#else
        else if (GLES2PixelUtil::getGLOriginFormat(src.format) == 0)
#endif
        {
            // Extents match, but format is not accepted as valid source format for GL
            // do conversion in temporary buffer
            allocateBuffer();
            scaled = mBuffer.getSubVolume(dstBox);
            PixelUtil::bulkPixelConversion(src, scaled);
        }
        else
        {
            allocateBuffer();
            // No scaling or conversion needed
            scaled = src;
            if (src.format == PF_R8G8B8)
            {
                scaled.format = PF_B8G8R8;
                PixelUtil::bulkPixelConversion(src, scaled);
            }
#if OGRE_PLATFORM == OGRE_PLATFORM_NACL
            if (src.format == PF_A8R8G8B8)
            {
                scaled.format = PF_A8B8G8R8;
                PixelUtil::bulkPixelConversion(src, scaled);
            }
#endif
        }

        upload(scaled, dstBox);
        freeBuffer();
    }
// Convert Ogre pixelbox extent to D3D rectangle
RECT toD3DRECTExtent(const PixelBox &lockBox)
{
    RECT prect;
    assert(lockBox.getDepth() == 1);
    prect.left = 0;
    prect.right = static_cast<LONG>(lockBox.getWidth());
    prect.top = 0;
    prect.bottom = static_cast<LONG>(lockBox.getHeight());
    return prect;
}
// Convert Ogre pixelbox extent to D3D box
D3DBOX toD3DBOXExtent(const PixelBox &lockBox)
{
    D3DBOX pbox;
    pbox.Left = 0;
    pbox.Right = static_cast<UINT>(lockBox.getWidth());
    pbox.Top = 0;
    pbox.Bottom = static_cast<UINT>(lockBox.getHeight());
    pbox.Front = 0;
    pbox.Back = static_cast<UINT>(lockBox.getDepth());
    return pbox;
}
//-----------------------------------------------------------------------------
void D3D11HardwarePixelBuffer::blitToMemory(const Image::Box &srcBox, const PixelBox &dst)
{
    // Decide on pixel format of temp surface
    PixelFormat tmpFormat = mFormat;
    if(D3D11Mappings::_getPF(dst.format) != DXGI_FORMAT_UNKNOWN)
    {
        tmpFormat = dst.format;
    }
    assert(srcBox.getDepth() == 1 && dst.getDepth() == 1);

    //This is a pointer to the texture we're trying to copy
    //Only implemented for 2D at the moment...
    ID3D11Texture2D *textureResource = mParentTexture->GetTex2D();

    // get the description of the texture
    D3D11_TEXTURE2D_DESC desc = {0};
    textureResource->GetDesc( &desc );
    //Alter the description to set up a staging texture
    desc.Usage = D3D11_USAGE_STAGING;
    //This texture is not bound to any part of the pipeline
    desc.BindFlags = 0;
    //Allow CPU Access
    desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
    //No Misc Flags
    desc.MiscFlags = 0;
    //Create the staging texture
    ID3D11Texture2D* pStagingTexture = NULL;
    mDevice->CreateTexture2D( &desc, NULL, &pStagingTexture );
    //Copy our texture into the staging texture
    mDevice.GetImmediateContext()->CopyResource( pStagingTexture, textureResource );
    //Create a mapped resource and map the staging texture to the resource
    D3D11_MAPPED_SUBRESOURCE mapped = {0};
    mDevice.GetImmediateContext()->Map( pStagingTexture, 0, D3D11_MAP_READ , 0, &mapped );

    // read the data out of the texture.
    unsigned int rPitch = mapped.RowPitch;
    BYTE *data = ((BYTE *)mapped.pData);

    //Using existing OGRE functions
    DXGI_MAPPED_RECT lrect;
    lrect.pBits = data;
    lrect.Pitch = rPitch;


    PixelBox locked(dst.getWidth(), dst.getHeight(), dst.getDepth(), tmpFormat);
    fromD3DLock(locked, lrect);
    PixelUtil::bulkPixelConversion(locked, dst);

    //Release the staging texture
    mDevice.GetImmediateContext()->Unmap( pStagingTexture, 0 );
    pStagingTexture->Release();
}
    void EGLWindow::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer)
    {
		if ((dst.left < 0) || (dst.right > mWidth) ||
			(dst.top < 0) || (dst.bottom > mHeight) ||
			(dst.front != 0) || (dst.back != 1))
		{
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
				"Invalid box.",
				"Win32Window::copyContentsToMemory" );
		}

		if (buffer == FB_AUTO)
		{
			buffer = mIsFullScreen? FB_FRONT : FB_BACK;
		}

		GLenum format = GLESPixelUtil::getGLOriginFormat(dst.format);
		GLenum type = GLESPixelUtil::getGLOriginDataType(dst.format);

		if ((format == 0) || (type == 0))
		{
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
				"Unsupported format.",
				"GtkEGLWindow::copyContentsToMemory" );
		}


		// Switch context if different from current one
		RenderSystem* rsys = Root::getSingleton().getRenderSystem();
		rsys->_setViewport(this->getViewport(0));

#if OGRE_NO_GLES3_SUPPORT == 0
        if(dst.getWidth() != dst.rowPitch)
            glPixelStorei(GL_PACK_ROW_LENGTH, dst.rowPitch);
#endif
		// Must change the packing to ensure no overruns!
		glPixelStorei(GL_PACK_ALIGNMENT, 1);

		//glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK);
        glReadPixels((GLint)0, (GLint)(mHeight - dst.getHeight()),
                     (GLsizei)dst.getWidth(), (GLsizei)dst.getHeight(),
                     format, type, dst.getTopLeftFrontPixelPtr());

		// restore default alignment
		glPixelStorei(GL_PACK_ALIGNMENT, 4);
#if OGRE_NO_GLES3_SUPPORT == 0
        glPixelStorei(GL_PACK_ROW_LENGTH, 0);
#endif
        
        PixelUtil::bulkPixelVerticalFlip(dst);
    }
void pixelBox(const PixelBox& box, isab::MapPlotter* plotter)
{
   std::vector<MC2Point> points;

   points.push_back(box.getTopLeft());
   points.push_back(box.getTopRight());
   points.push_back(box.getBottomRight());
   points.push_back(box.getBottomLeft());
   points.push_back(box.getTopLeft());

   plotter->setPenColor(255, 0, 0);
   plotter->setLineWidth(3);
   
   plotter->drawPolyLine(points.begin(), points.end());
}
	//-----------------------------------------------------------------------------  
	// Util functions to convert a D3D locked box to a pixel box
	void D3D10HardwarePixelBuffer::fromD3DLock(PixelBox &rval, const DXGI_MAPPED_RECT &lrect)
	{
		rval.rowPitch = lrect.Pitch / PixelUtil::getNumElemBytes(rval.format);
		rval.slicePitch = rval.rowPitch * rval.getHeight();
		assert((lrect.Pitch % PixelUtil::getNumElemBytes(rval.format))==0);
		rval.data = lrect.pBits;
	}
示例#11
0
///  _Tool_ tex ..........................
//  (remove alpha channel for ter tex prv img)
void App::ToolTexAlpha()
{
	Ogre::Image im;
	im.load("jungle_5d.png", "General");

	PixelBox pb = im.getPixelBox();
	int w = pb.getWidth(), h = pb.getHeight();
	for(int j=0; j < h; ++j)
	for(int i=0; i < w; ++i)
	{
		ColourValue c = pb.getColourAt(i,j,0);
		c.a = 1.f;
		pb.setColourAt(c,i,j,0);
	}
	im.save(PATHMANAGER::Data()+"/prv.png");
}
示例#12
0
    void EGLWindow::copyContentsToMemory(const Box& src, const PixelBox &dst, FrameBuffer buffer)
    {
        if(src.right > mWidth || src.bottom > mHeight || src.front != 0 || src.back != 1
        || dst.getWidth() != src.getWidth() || dst.getHeight() != src.getHeight() || dst.getDepth() != 1)
        {
            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid box.", "EGLWindow::copyContentsToMemory");
        }

        if (buffer == FB_AUTO)
        {
            buffer = mIsFullScreen? FB_FRONT : FB_BACK;
        }

        static_cast<GLRenderSystemCommon*>(Root::getSingleton().getRenderSystem())
                ->_copyContentsToMemory(getViewport(0), src, dst, buffer);
    }
示例#13
0
void ShVarItem::setCurrentValue(int key0, int key1)
{
	if (key0 >= 0 && key1 >= 0 && data(DF_WATCHED).toBool()) {
		if (data(DF_DATA_PIXELBOX).value<void*>() != NULL) {
			PixelBox *fb = getPixelBoxPointer();
			if (fb) {
				QVariant value;
				bool validValue = fb->getDataValue(key0, key1, &value);
				if (validValue) {
					setData(DF_DEBUG_SELECTED_VALUE, value.toString());
					return;
				}
			}
		}
		setData(DF_DEBUG_SELECTED_VALUE, "?");
		return;
	}
	setData(DF_DEBUG_SELECTED_VALUE, QVariant());
}
示例#14
0
    //-----------------------------------------------------------------------
    void ILUtil::toOgre(const PixelBox &dst) 
    {
		if(!dst.isConsecutive())
			OGRE_EXCEPT( Exception::ERR_NOT_IMPLEMENTED,
                "Destination must currently be consecutive",
                "ILUtil::ilToOgre" ) ;
		if(dst.getWidth() != static_cast<size_t>(ilGetInteger( IL_IMAGE_WIDTH )) ||
        	dst.getHeight() != static_cast<size_t>(ilGetInteger( IL_IMAGE_HEIGHT )) ||
        	dst.getDepth() != static_cast<size_t>(ilGetInteger( IL_IMAGE_DEPTH )))
			OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS,
                "Destination dimensions must equal IL dimension",
                "ILUtil::ilToOgre" ) ;
        
        int ilfmt = ilGetInteger( IL_IMAGE_FORMAT );
        int iltp = ilGetInteger( IL_IMAGE_TYPE );

		// Check if in-memory format just matches
		// If yes, we can just copy it and save conversion
		ILFormat ifmt = OgreFormat2ilFormat( dst.format );
		if(ifmt.format == ilfmt && ILabs(ifmt.type) == ILabs(iltp)) {
            memcpy(dst.data, ilGetData(), ilGetInteger( IL_IMAGE_SIZE_OF_DATA )); 
            return;
        }
		// Try if buffer is in a known OGRE format so we can use OGRE its
		// conversion routines
		PixelFormat bufFmt = ilFormat2OgreFormat((int)ilfmt, (int)iltp);
		
		ifmt = OgreFormat2ilFormat( bufFmt );
		if(ifmt.format == ilfmt && ILabs(ifmt.type) == ILabs(iltp))
		{
			// IL format matches another OGRE format
			PixelBox src(dst.getWidth(), dst.getHeight(), dst.getDepth(), bufFmt, ilGetData());
			PixelUtil::bulkPixelConversion(src, dst);
			return;
		}
		
        // Thee extremely slow method
        if(iltp == IL_UNSIGNED_BYTE || iltp == IL_BYTE) 
        {
            ilToOgreInternal(static_cast<uint8*>(dst.data), dst.format, (uint8)0x00,(uint8)0x00,(uint8)0x00,(uint8)0xFF);
        } 
        else if(iltp == IL_FLOAT)
        {
            ilToOgreInternal(static_cast<uint8*>(dst.data), dst.format, 0.0f,0.0f,0.0f,1.0f);          
        }
		else if(iltp == IL_SHORT || iltp == IL_UNSIGNED_SHORT)
        {
			ilToOgreInternal(static_cast<uint8*>(dst.data), dst.format, 
				(uint16)0x0000,(uint16)0x0000,(uint16)0x0000,(uint16)0xFFFF); 
        }
        else 
        {
            OGRE_EXCEPT( Exception::ERR_NOT_IMPLEMENTED,
                "Cannot convert this DevIL type",
                "ILUtil::ilToOgre" ) ;
        }
    }
示例#15
0
void TextureViewGL::ReadPixels(RenderContext_Base_GL* gl, TextureBase::ReadPixelUpdateParams& params) {
	if (params.lock.test_and_set(std::memory_order_release))
		return;
	PixelBox* pixels = params.box;
	gl->ActivateTexture(target, texture);
	Size dim = gl->GetTextureParams(target);

	pixels->data = static_cast<uint8*>(
		NEX_ALLOC(dim.dx * dim.dy * pixelFormat.pixelSize, MEMCAT_GENERAL));
	pixels->left = 0;
	pixels->right = dim.dx;
	pixels->top = 0;
	pixels->bottom = dim.dy;
	pixels->front = 0;
	pixels->back = 1;
	pixels->format = pixelFormat.textureFormat;
	pixels->deleteData = true;
	gl->GetTextureData(target, pixelFormat.internalFormat, pixelFormat.dataType, pixels->data);
	pixels->CalculatePitches();
}
示例#16
0
///  _Tool_ tex ..........................
//  (split 1 rgba terrain texture to 2, 1st rgb and 2nd with alpha in red)
void CGui::ToolTexAlpha()
{
	strlist li;
	string data = PATHMANAGER::Data()+"/terrain";
	PATHMANAGER::DirList(data, li);
	//PATHMANAGER::DirList(data+"2", li);

	int ii=0;
	for (strlist::iterator i = li.begin(); i != li.end(); ++i,++ii)
	if (/*ii < 3 &&*/ !StringUtil::match(*i, "*.txt", false))
	{
		String n = *i;
		Image im;
		im.load(n, "General");

		PixelBox pb = im.getPixelBox();
		//pb.setConsecutive();
		int w = pb.getWidth(), h = pb.getHeight();

		uchar* rgb = new uchar[w*h*3];
		uchar* aa = new uchar[w*h];
		register int i,j,a=0,b=0;
		for (j=0; j < h; ++j)
		for (i=0; i < w; ++i)
		{
			//pb.data
			ColourValue c = pb.getColourAt(i,j,0);
			rgb[a++] = c.b * 255.f;
			rgb[a++] = c.g * 255.f;
			rgb[a++] = c.r * 255.f;
			aa[b++] = c.a * 255.f;
		}
		Ogre::Image ic,ia;
		ic.loadDynamicImage(rgb, w,h, PF_R8G8B8);
		ic.save(PATHMANAGER::Data()+"/"+n+"_d.png");
		ia.loadDynamicImage(aa, w,h, PF_L8);
		ia.save(PATHMANAGER::Data()+"/"+n+"_s.png");
		delete[]rgb;  delete[]aa;
	}
}
示例#17
0
void NearestSampler(PixelBox& dest, const PixelBox& src) {
	size_t bytesPerPix = BytesPerPixel(src.format);
	NEX_ASSERT(bytesPerPix == BytesPerPixel(dest.format));

	float dstep = ((float) src.GetDepth() / (float) dest.GetDepth()) * .5f;
	float hstep = ((float) src.GetHeight() / (float) dest.GetHeight()) * .5f;
	float wstep = ((float) src.GetWidth() / (float) dest.GetWidth()) * .5f;

	for (uint32 d = dest.front; d < dest.back; ++d) {
		size_t doff = (uint32) (dstep * (src.slicePixelPitch * d * 2 + 1));
		NEX_ASSERT(doff >= 0 && doff <= src.slicePixelPitch * d);
		void* destPlane = reinterpret_cast<uint8*>(dest.data)
				+ d * dest.slicePixelPitch * bytesPerPix;
		for (uint32 h = dest.top; h < dest.bottom; ++h) {

			size_t hoff = (uint32) ((2 * h * src.rowPixelPitch + 1) * hstep);
			NEX_ASSERT(hoff >= 0 && hoff <= src.rowPixelPitch * h);
			uint8* destRow = reinterpret_cast<uint8*>(destPlane)
					+ h * dest.rowPixelPitch * bytesPerPix;
			for (uint32 w = dest.left; w < dest.right; ++w) {
				size_t woff = (size_t) ((2 * w + 1) * wstep);
				NEX_ASSERT(woff >= 0 && woff <= w);
				uint8* srcData = reinterpret_cast<uint8*>(src.data)
						+ (doff + hoff + woff) * bytesPerPix;
				// src offset
				uint8* destData = (destRow + w * bytesPerPix);
				for (uint32 j = 0; j < bytesPerPix; ++j)
					destData[j] = srcData[j];
			}
		}
	}
}
    void GL3PlusHardwarePixelBuffer::blitFromMemory(const PixelBox &src, const Image::Box &dstBox)
    {
        if (!mBuffer.contains(dstBox))
        {
            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
                        "Destination box out of range",
                        "GL3PlusHardwarePixelBuffer::blitFromMemory");
        }

        PixelBox scaled;

        if (src.getWidth() != dstBox.getWidth() ||
            src.getHeight() != dstBox.getHeight() ||
            src.getDepth() != dstBox.getDepth())
        {
            // Scale to destination size.
            // This also does pixel format conversion if needed.
            allocateBuffer( mSizeInBytes );
            scaled = mBuffer.getSubVolume(dstBox);
            Image::scale(src, scaled, Image::FILTER_BILINEAR);
        }
        else if (GL3PlusPixelUtil::getGLOriginFormat(src.format) == 0)
        {
            // Extents match, but format is not accepted as valid
            // source format for GL. Do conversion in temporary buffer.
            allocateBuffer( mSizeInBytes );
            scaled = mBuffer.getSubVolume(dstBox);
            PixelUtil::bulkPixelConversion(src, scaled);
        }
        else
        {
            allocateBuffer( mSizeInBytes );
            // No scaling or conversion needed.
            scaled = src;
        }

        upload(scaled, dstBox);
        freeBuffer();
    }
void fromD3DLock(PixelBox &rval, const D3DLOCKED_BOX &lbox)
{
    size_t bpp = PixelUtil::getNumElemBytes(rval.format);
    if (bpp != 0)
    {
        rval.rowPitch = lbox.RowPitch / bpp;
        rval.slicePitch = lbox.SlicePitch / bpp;
        assert((lbox.RowPitch % bpp)==0);
        assert((lbox.SlicePitch % bpp)==0);
    }
    else if (PixelUtil::isCompressed(rval.format))
    {
        rval.rowPitch = rval.getWidth();
        rval.slicePitch = rval.getWidth() * rval.getHeight();
    }
    else
    {
        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
            "Invalid pixel format", "fromD3DLock");
    }
    rval.data = lbox.pBits;
}
    //-----------------------------------------------------------------------------  
    void GLES2TextureBuffer::download(const PixelBox &data)
    {
#if 0 || defined(GL_NV_get_tex_image)
        if(data.getWidth() != getWidth() ||
            data.getHeight() != getHeight() ||
            data.getDepth() != getDepth())
            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "only download of entire buffer is supported by GL",
                "GLTextureBuffer::download");
        glBindTexture( mTarget, mTextureID );
        if(PixelUtil::isCompressed(data.format))
        {
            if(data.format != mFormat || !data.isConsecutive())
                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, 
                "Compressed images must be consecutive, in the source format",
                "GLTextureBuffer::download");
            // Data must be consecutive and at beginning of buffer as PixelStorei not allowed
            // for compressed formate
            glGetCompressedTexImageNV(mFaceTarget, mLevel, data.data);
        } 
        else
        {
            if((data.getWidth()*PixelUtil::getNumElemBytes(data.format)) & 3) {
                // Standard alignment of 4 is not right
                glPixelStorei(GL_PACK_ALIGNMENT, 1);
            }
            // We can only get the entire texture
            glGetTexImageNV(mFaceTarget, mLevel, 
                GLES2PixelUtil::getGLOriginFormat(data.format), GLES2PixelUtil::getGLOriginDataType(data.format),
                data.data);
            // Restore defaults
            glPixelStorei(GL_PACK_ALIGNMENT, 4);
        }
#else
        OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, 
                    "Downloading texture buffers is not supported by OpenGL ES",
                    "GLES2TextureBuffer::download");
#endif
    }
示例#21
0
///  _Tool_ brushes prv  ......................................................
//  update all Brushes png
void CGui::ToolBrushesPrv()
{
	Image im;
	for (int i=0; i < app->brSetsNum; ++i)
	{
		app->SetBrushPreset(i);
		app->brushPrvTex->convertToImage(im);
		im.save("data/editor/brush"+toStr(i)+".png");
		// todo: ?brush presets in xml, auto upd prvs-
	}

	#if 1
	///---- combine all images into one ----
	const int ii = 86;
	Image ir;  ir.load("brushes-e.png","General");
	for (int i=0; i <= ii; ++i)
	{
		String s = "brush" + toStr(i) + ".png";
		im.load(s,"General");

		PixelBox pb = im.getPixelBox();
		int xx = pb.getWidth(), yy = pb.getHeight();
		
		//void * pb.data
		int a = (i%16)*128, b = (i/16)*128;
		register int x,y;  ColourValue c;
		for (y = 0; y < yy; ++y)
		for (x = 0; x < xx; ++x)
		{
			c = im.getColourAt(x,y,0);
			ir.setColourAt(c,a+x,b+y,0);
		}
	}
	ir.save("brushes.png");
	#endif
}
示例#22
0
    void SDLWindow::copyContentsToMemory(const PixelBox &dst, FrameBuffer buffer)
    {
        if (dst.getWidth() > mWidth ||
            dst.getHeight() > mHeight ||
            dst.front != 0 || dst.back != 1)
        {
            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
                        "Invalid box.",
                        "SDLWindow::copyContentsToMemory" );
        }

        if (buffer == FB_AUTO)
        {
            buffer = mIsFullScreen? FB_FRONT : FB_BACK;
        }

        GLenum format = Ogre::GL3PlusPixelUtil::getGLOriginFormat(dst.format);
        GLenum type = Ogre::GL3PlusPixelUtil::getGLOriginDataType(dst.format);

        if ((format == GL_NONE) || (type == 0))
        {
            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
                        "Unsupported format.",
                        "SDLWindow::copyContentsToMemory" );
        }

        if(dst.getWidth() != dst.rowPitch)
        {
            glPixelStorei(GL_PACK_ROW_LENGTH, dst.rowPitch);
        }
        if((dst.getWidth()*Ogre::PixelUtil::getNumElemBytes(dst.format)) & 3)
        {
            // Standard alignment of 4 is not right
            glPixelStorei(GL_PACK_ALIGNMENT, 1);
        }

        glReadBuffer((buffer == FB_FRONT)? GL_FRONT : GL_BACK);
        glReadPixels((GLint)0, (GLint)(mHeight - dst.getHeight()),
                     (GLsizei)dst.getWidth(), (GLsizei)dst.getHeight(),
                     format, type, dst.getTopLeftFrontPixelPtr());

        glPixelStorei(GL_PACK_ALIGNMENT, 4);
        glPixelStorei(GL_PACK_ROW_LENGTH, 0);

        PixelUtil::bulkPixelVerticalFlip(dst);
    }
    void GLESHardwarePixelBuffer::blitToMemory(const Image::Box &srcBox, const PixelBox &dst)
    {
        if (!mBuffer.contains(srcBox))
        {
            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
                        "source box out of range",
                        "GLESHardwarePixelBuffer::blitToMemory");
        }

        if (srcBox.left == 0 && srcBox.right == getWidth() &&
            srcBox.top == 0 && srcBox.bottom == getHeight() &&
            srcBox.front == 0 && srcBox.back == getDepth() &&
            dst.getWidth() == getWidth() &&
            dst.getHeight() == getHeight() &&
            dst.getDepth() == getDepth() &&
            GLESPixelUtil::getGLOriginFormat(dst.format) != 0)
        {
            // The direct case: the user wants the entire texture in a format supported by GL
            // so we don't need an intermediate buffer
            download(dst);
        }
        else
        {
            // Use buffer for intermediate copy
            allocateBuffer();
            // Download entire buffer
            download(mBuffer);
            if(srcBox.getWidth() != dst.getWidth() ||
                srcBox.getHeight() != dst.getHeight() ||
                srcBox.getDepth() != dst.getDepth())
            {
                // We need scaling
                Image::scale(mBuffer.getSubVolume(srcBox), dst, Image::FILTER_BILINEAR);
            }
            else
            {
                // Just copy the bit that we need
                PixelUtil::bulkPixelConversion(mBuffer.getSubVolume(srcBox), dst);
            }
            freeBuffer();
        }
    }
int TileBoundsCalculator::_calculateSplitX(PixelBox& b)
{
  double total = _sumPixels(b);

  double left = _sumPixels(b.getColumnBox(b.minX));

  int best = (b.maxX + b.minX) / 2;
  double bestSum = numeric_limits<double>::max();

  double thisSlop = _slop + 1.0 / (double)(b.maxX - b.minX);

  if (b.getWidth() < 6)
  {
    throw HootException("The input box must be at least six pixels high.");
  }

  for (int c = b.minX + 2; c < b.maxX - 2; c++)
  {
    double colSum = _sumPixels(b.getColumnBox(c));
    double colSumMin = _sumPixels(b.getColumnBox(c), _min) +
      _sumPixels(b.getColumnBox(c + 1), _min);
    left += colSum;

    double slop = abs(0.5 - left / total);
    if ((slop < thisSlop) && colSumMin < bestSum)
    {
      best = c;
      bestSum = colSumMin;
    }
  }

  if (bestSum == numeric_limits<double>::max())
  {
    LOG_WARN("bestSum isn't valid. " << b.toString());
  }

  return best;
}
int TileBoundsCalculator::_calculateSplitY(const PixelBox& b)
{
  double total = _sumPixels(b);

  double bottom = _sumPixels(b.getRowBox(b.minY));

  int best = (b.maxY + b.minY) / 2;
  double bestSum = numeric_limits<double>::max();

  double thisSlop = _slop + 1.0 / (double)(b.maxY - b.minY);

  if (b.getHeight() < 6)
  {
    throw HootException("The input box must be at least six pixels high.");
  }

  for (int r = b.minY + 2; r < b.maxY - 2; r++)
  {
    double rowSum = _sumPixels(b.getRowBox(r));
    double rowSumMin = _sumPixels(b.getRowBox(r), _min) + _sumPixels(b.getRowBox(r + 1), _min);
    bottom += rowSum;

    double slop = abs(0.5 - bottom / total);
    if ((slop < thisSlop) && rowSumMin < bestSum)
    {
      best = r;
      bestSum = rowSumMin;
    }
  }

  if (bestSum == numeric_limits<double>::max())
  {
    LOG_WARN("bestSum isn't valid. " << b.toString() << " total: " << total << " size: " <<
             b.maxY - b.minY);
  }

  return best;
}
示例#26
0
    //-----------------------------------------------------------------------
    void Image::scale(const PixelBox &src, const PixelBox &scaled, Filter filter) 
    {
        assert(PixelUtil::isAccessible(src.format));
        assert(PixelUtil::isAccessible(scaled.format));
        MemoryDataStreamPtr buf; // For auto-delete
        PixelBox temp;
        switch (filter) 
        {
        default:
        case FILTER_NEAREST:
            if(src.format == scaled.format) 
            {
                // No intermediate buffer needed
                temp = scaled;
            }
            else
            {
                // Allocate temporary buffer of destination size in source format 
                temp = PixelBox(scaled.getWidth(), scaled.getHeight(), scaled.getDepth(), src.format);
                buf.bind(OGRE_NEW MemoryDataStream(temp.getConsecutiveSize()));
                temp.data = buf->getPtr();
            }
            // super-optimized: no conversion
            switch (PixelUtil::getNumElemBytes(src.format)) 
            {
            case 1: NearestResampler<1>::scale(src, temp); break;
            case 2: NearestResampler<2>::scale(src, temp); break;
            case 3: NearestResampler<3>::scale(src, temp); break;
            case 4: NearestResampler<4>::scale(src, temp); break;
            case 6: NearestResampler<6>::scale(src, temp); break;
            case 8: NearestResampler<8>::scale(src, temp); break;
            case 12: NearestResampler<12>::scale(src, temp); break;
            case 16: NearestResampler<16>::scale(src, temp); break;
            default:
                // never reached
                assert(false);
            }
            if(temp.data != scaled.data)
            {
                // Blit temp buffer
                PixelUtil::bulkPixelConversion(temp, scaled);
            }
            break;

        case FILTER_LINEAR:
        case FILTER_BILINEAR:
            switch (src.format) 
            {
            case PF_L8: case PF_A8: case PF_BYTE_LA:
            case PF_R8G8B8: case PF_B8G8R8:
            case PF_R8G8B8A8: case PF_B8G8R8A8:
            case PF_A8B8G8R8: case PF_A8R8G8B8:
            case PF_X8B8G8R8: case PF_X8R8G8B8:
                if(src.format == scaled.format) 
                {
                    // No intermediate buffer needed
                    temp = scaled;
                }
                else
                {
                    // Allocate temp buffer of destination size in source format 
                    temp = PixelBox(scaled.getWidth(), scaled.getHeight(), scaled.getDepth(), src.format);
                    buf.bind(OGRE_NEW MemoryDataStream(temp.getConsecutiveSize()));
                    temp.data = buf->getPtr();
                }
                // super-optimized: byte-oriented math, no conversion
                switch (PixelUtil::getNumElemBytes(src.format)) 
                {
                case 1: LinearResampler_Byte<1>::scale(src, temp); break;
                case 2: LinearResampler_Byte<2>::scale(src, temp); break;
                case 3: LinearResampler_Byte<3>::scale(src, temp); break;
                case 4: LinearResampler_Byte<4>::scale(src, temp); break;
                default:
                    // never reached
                    assert(false);
                }
                if(temp.data != scaled.data)
                {
                    // Blit temp buffer
                    PixelUtil::bulkPixelConversion(temp, scaled);
                }
                break;
            case PF_FLOAT32_RGB:
            case PF_FLOAT32_RGBA:
                if (scaled.format == PF_FLOAT32_RGB || scaled.format == PF_FLOAT32_RGBA)
                {
                    // float32 to float32, avoid unpack/repack overhead
                    LinearResampler_Float32::scale(src, scaled);
                    break;
                }
                // else, fall through
            default:
                // non-optimized: floating-point math, performs conversion but always works
                LinearResampler::scale(src, scaled);
            }
            break;
        }
    }
    void GLESTextureBuffer::buildMipmaps(const PixelBox &data)
    {
        int width;
        int height;
        int logW;
        int logH;
        int level;
        PixelBox scaled = data;
        scaled.data = data.data;
        scaled.left = data.left;
        scaled.right = data.right;
        scaled.top = data.top;
        scaled.bottom = data.bottom;
        scaled.front = data.front;
        scaled.back = data.back;

        width = data.getWidth();
        height = data.getHeight();

        logW = computeLog(width);
        logH = computeLog(height);
        level = (logW > logH ? logW : logH);

        for (int mip = 0; mip <= level; mip++)
        {
            GLenum glFormat = GLESPixelUtil::getGLOriginFormat(scaled.format);
            GLenum dataType = GLESPixelUtil::getGLOriginDataType(scaled.format);

            glTexImage2D(mFaceTarget,
                         mip,
                         glFormat,
                         width, height,
                         0,
                         glFormat,
                         dataType,
                         scaled.data);

            GL_CHECK_ERROR;

            if (mip != 0)
            {
                delete[] (uint8*) scaled.data;
                scaled.data = 0;
            }

            if (width > 1)
            {
                width = width / 2;
            }

            if (height > 1)
            {
                height = height / 2;
            }

            int sizeInBytes = PixelUtil::getMemorySize(width, height, 1,
                                                       data.format);
            scaled = PixelBox(width, height, 1, data.format);
            scaled.data = new uint8[sizeInBytes];
            Image::scale(data, scaled, Image::FILTER_LINEAR);
        }
    }
    //-----------------------------------------------------------------------------  
    // blitFromMemory doing hardware trilinear scaling
    void GLESTextureBuffer::blitFromMemory(const PixelBox &src_orig, const Image::Box &dstBox)
    {
        // Fall back to normal GLHardwarePixelBuffer::blitFromMemory in case 
        // - FBO is not supported
        // - Either source or target is luminance due doesn't looks like supported by hardware
        // - the source dimensions match the destination ones, in which case no scaling is needed
        if(!GL_OES_framebuffer_object ||
           PixelUtil::isLuminance(src_orig.format) ||
           PixelUtil::isLuminance(mFormat) ||
           (src_orig.getWidth() == dstBox.getWidth() &&
            src_orig.getHeight() == dstBox.getHeight() &&
            src_orig.getDepth() == dstBox.getDepth()))
        {
            GLESHardwarePixelBuffer::blitFromMemory(src_orig, dstBox);
            return;
        }
        if(!mBuffer.contains(dstBox))
            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Destination box out of range",
                        "GLESTextureBuffer::blitFromMemory");
        // For scoped deletion of conversion buffer
        MemoryDataStreamPtr buf;
        PixelBox src;
        
        // First, convert the srcbox to a OpenGL compatible pixel format
        if(GLESPixelUtil::getGLOriginFormat(src_orig.format) == 0)
        {
            // Convert to buffer internal format
            buf.bind(OGRE_NEW MemoryDataStream(PixelUtil::getMemorySize(src_orig.getWidth(), src_orig.getHeight(), src_orig.getDepth(),
                                                                   mFormat)));
            src = PixelBox(src_orig.getWidth(), src_orig.getHeight(), src_orig.getDepth(), mFormat, buf->getPtr());
            PixelUtil::bulkPixelConversion(src_orig, src);
        }
        else
        {
            // No conversion needed
            src = src_orig;
        }
        
        // Create temporary texture to store source data
        GLuint id;
        GLenum target = GL_TEXTURE_2D;
        GLsizei width = GLESPixelUtil::optionalPO2(src.getWidth());
        GLsizei height = GLESPixelUtil::optionalPO2(src.getHeight());
        GLenum format = GLESPixelUtil::getClosestGLInternalFormat(src.format);
        GLenum datatype = GLESPixelUtil::getGLOriginDataType(src.format);
        // Generate texture name
        glGenTextures(1, &id);
        GL_CHECK_ERROR;
        
        // Set texture type
        glBindTexture(target, id);
        GL_CHECK_ERROR;
        
        // Set automatic mipmap generation; nice for minimisation
        glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE );
        GL_CHECK_ERROR;

        // Allocate texture memory
        glTexImage2D(target, 0, format, width, height, 0, format, datatype, 0);
        GL_CHECK_ERROR;

        // GL texture buffer
        GLESTextureBuffer tex(BLANKSTRING, target, id, width, height, format, src.format,
                              0, 0, (Usage)(TU_AUTOMIPMAP|HBU_STATIC_WRITE_ONLY), false, false, 0);
        
        // Upload data to 0,0,0 in temporary texture
        Image::Box tempTarget(0, 0, 0, src.getWidth(), src.getHeight(), src.getDepth());
        tex.upload(src, tempTarget);
        
        // Blit
        blitFromTexture(&tex, tempTarget, dstBox);
        
        // Delete temp texture
        glDeleteTextures(1, &id);
        GL_CHECK_ERROR;
    }
    void GLESTextureBuffer::upload(const PixelBox &data, const Image::Box &dest)
    {
        glBindTexture(mTarget, mTextureID);
        GL_CHECK_ERROR;

        if (PixelUtil::isCompressed(data.format))
        {
            if(data.format != mFormat || !data.isConsecutive())
                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
                            "Compressed images must be consecutive, in the source format",
                            "GLESTextureBuffer::upload");

            GLenum format = GLESPixelUtil::getClosestGLInternalFormat(mFormat);
            // Data must be consecutive and at beginning of buffer as PixelStorei not allowed
            // for compressed formats
            if (dest.left == 0 && dest.top == 0)
            {
                glCompressedTexImage2D(mFaceTarget, mLevel,
                                       format,
                                       dest.getWidth(),
                                       dest.getHeight(),
                                       0,
                                       data.getConsecutiveSize(),
                                       data.data);
                GL_CHECK_ERROR;
            }
            else
            {
                glCompressedTexSubImage2D(mFaceTarget, mLevel,
                                          dest.left, dest.top,
                                          dest.getWidth(), dest.getHeight(),
                                          format, data.getConsecutiveSize(),
                                          data.data);

                GL_CHECK_ERROR;
            }
        }
        else if (mSoftwareMipmap)
        {
            if (data.getWidth() != data.rowPitch)
            {
                // TODO
                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
                            "Unsupported texture format",
                            "GLESTextureBuffer::upload");
            }

            if (data.getHeight() * data.getWidth() != data.slicePitch)
            {
                // TODO
                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
                            "Unsupported texture format",
                            "GLESTextureBuffer::upload");
            }

            glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
            GL_CHECK_ERROR;
            buildMipmaps(data);
        }
        else
        {
            if(data.getWidth() != data.rowPitch)
            {
                // TODO
                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
                            "Unsupported texture format",
                            "GLESTextureBuffer::upload");
            }

            if(data.getHeight()*data.getWidth() != data.slicePitch)
            {
                // TODO
                OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
                            "Unsupported texture format",
                            "GLESTextureBuffer::upload");
            }

            if ((data.getWidth() * PixelUtil::getNumElemBytes(data.format)) & 3) {
                // Standard alignment of 4 is not right
                glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
                GL_CHECK_ERROR;
            }

//            LogManager::getSingleton().logMessage("GLESTextureBuffer::upload - ID: " + StringConverter::toString(mTextureID) +
//                                                  " Format: " + PixelUtil::getFormatName(data.format) +
//                                                  " Origin format: " + StringConverter::toString(GLESPixelUtil::getGLOriginFormat(data.format, 0, ' ', std::ios::hex)) +
//                                                  " Data type: " + StringConverter::toString(GLESPixelUtil::getGLOriginDataType(data.format, 0, ' ', std::ios::hex))
//                                                  );
            glTexSubImage2D(mFaceTarget,
                            mLevel,
                            dest.left, dest.top,
                            dest.getWidth(), dest.getHeight(),
                            GLESPixelUtil::getGLOriginFormat(data.format),
                            GLESPixelUtil::getGLOriginDataType(data.format),
                            data.data);
            GL_CHECK_ERROR;
        }

        glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
        GL_CHECK_ERROR;
    }
示例#30
0
	//--------------------------------------------------------------------------
    void Texture::_loadImages( const ConstImagePtrList& images )
    {
		if(images.size() < 1)
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Cannot load empty vector of images",
			 "Texture::loadImages");
        
		// Set desired texture size and properties from images[0]
		mSrcWidth = mWidth = images[0]->getWidth();
		mSrcHeight = mHeight = images[0]->getHeight();
		mSrcDepth = mDepth = images[0]->getDepth();

        // Get source image format and adjust if required
        mSrcFormat = images[0]->getFormat();
        if (mTreatLuminanceAsAlpha && mSrcFormat == PF_L8)
        {
            mSrcFormat = PF_A8;
        }

        if (mDesiredFormat != PF_UNKNOWN)
        {
            // If have desired format, use it
            mFormat = mDesiredFormat;
        }
        else
        {
            // Get the format according with desired bit depth
            mFormat = PixelUtil::getFormatForBitDepths(mSrcFormat, mDesiredIntegerBitDepth, mDesiredFloatBitDepth);
        }

		// The custom mipmaps in the image have priority over everything
        size_t imageMips = images[0]->getNumMipmaps();

		if(imageMips > 0) {
			mNumMipmaps = mNumRequestedMipmaps = images[0]->getNumMipmaps();
			// Disable flag for auto mip generation
			mUsage &= ~TU_AUTOMIPMAP;
		}
		
        // Create the texture
        createInternalResources();
		// Check if we're loading one image with multiple faces
		// or a vector of images representing the faces
		size_t faces;
		bool multiImage; // Load from multiple images?
		if(images.size() > 1)
		{
			faces = images.size();
			multiImage = true;
		}
		else
		{
			faces = images[0]->getNumFaces();
			multiImage = false;
		}
		
		// Check wether number of faces in images exceeds number of faces
		// in this texture. If so, clamp it.
		if(faces > getNumFaces())
			faces = getNumFaces();
		
        if (TextureManager::getSingleton().getVerbose()) {
            // Say what we're doing
            StringUtil::StrStreamType str;
            str << "Texture: " << mName << ": Loading " << faces << " faces"
                << "(" << PixelUtil::getFormatName(images[0]->getFormat()) << "," <<
                images[0]->getWidth() << "x" << images[0]->getHeight() << "x" << images[0]->getDepth() <<
                ") with ";
            if (!(mMipmapsHardwareGenerated && mNumMipmaps == 0))
                str << mNumMipmaps;
            if(mUsage & TU_AUTOMIPMAP)
            {
                if (mMipmapsHardwareGenerated)
                    str << " hardware";

                str << " generated mipmaps";
            }
            else
            {
                str << " custom mipmaps";
            }
            if(multiImage)
                str << " from multiple Images.";
            else
                str << " from Image.";
            // Scoped
            {
                // Print data about first destination surface
                HardwarePixelBufferSharedPtr buf = getBuffer(0, 0); 
                str << " Internal format is " << PixelUtil::getFormatName(buf->getFormat()) << 
                "," << buf->getWidth() << "x" << buf->getHeight() << "x" << buf->getDepth() << ".";
            }
            LogManager::getSingleton().logMessage( 
                    LML_NORMAL, str.str());
        }
		
		// Main loading loop
        // imageMips == 0 if the image has no custom mipmaps, otherwise contains the number of custom mips
        for(size_t mip = 0; mip<=imageMips; ++mip)
        {
            for(size_t i = 0; i < faces; ++i)
            {
                PixelBox src;
                if(multiImage)
                {
                    // Load from multiple images
                    src = images[i]->getPixelBox(0, mip);
                }
                else
                {
                    // Load from faces of images[0]
                    src = images[0]->getPixelBox(i, mip);
                }
    
                // Sets to treated format in case is difference
                src.format = mSrcFormat;

                if(mGamma != 1.0f) {
                    // Apply gamma correction
                    // Do not overwrite original image but do gamma correction in temporary buffer
                    MemoryDataStreamPtr buf; // for scoped deletion of conversion buffer
                    buf.bind(OGRE_NEW MemoryDataStream(
                        PixelUtil::getMemorySize(
                            src.getWidth(), src.getHeight(), src.getDepth(), src.format)));
                    
                    PixelBox corrected = PixelBox(src.getWidth(), src.getHeight(), src.getDepth(), src.format, buf->getPtr());
                    PixelUtil::bulkPixelConversion(src, corrected);
                    
                    Image::applyGamma(static_cast<uint8*>(corrected.data), mGamma, corrected.getConsecutiveSize(), 
                        static_cast<uchar>(PixelUtil::getNumElemBits(src.format)));
    
                    // Destination: entire texture. blitFromMemory does the scaling to
                    // a power of two for us when needed
                    getBuffer(i, mip)->blitFromMemory(corrected);
                }
                else 
                {
                    // Destination: entire texture. blitFromMemory does the scaling to
                    // a power of two for us when needed
                    getBuffer(i, mip)->blitFromMemory(src);
                }
                
            }
        }
        // Update size (the final size, not including temp space)
        mSize = getNumFaces() * PixelUtil::getMemorySize(mWidth, mHeight, mDepth, mFormat);

    }