//----------------------------------------------------------------------------//
Texture* OgreImageCodec::load(const RawDataContainer& data, Texture* result)
{
    using namespace Ogre;

    // wrap the buffer of the RawDataContainer with an Ogre::MemoryDataStream.
    DataStreamPtr stream(
        new MemoryDataStream(
            const_cast<void*>(static_cast<const void*>(data.getDataPtr())),
            data.getSize(), false));

    // load the image
    Ogre::Image image;
    image.load(stream);

    // discover the pixel format and number of pixel components
    Texture::PixelFormat format;
    int components;
    switch (image.getFormat())
    {
        case PF_R8G8B8:
            format = Texture::PF_RGB;
            components = 3;
            break;

        case PF_A8R8G8B8:
            format = Texture::PF_RGBA;
            components = 4;
            break;

        default:
            throw FileIOException("OgreImageCodec::load: File data was of an "
                                  "unsupported format.");
            break;
    }

    // do the old switcharoo on R and B...
    // (we could 'fix' this in the CEGUI::OgreTexture, but that would break all
    // the other ImageCodecs when used with the Ogre renderer, hence we don't)
    uchar* dat = image.getData();
    for (uint j = 0; j < image.getHeight(); ++j)
    {
        for (uint i = 0; i < image.getWidth(); ++i)
        {
            uchar tmp = dat[i * components + 0];
            dat[i * components + 0] = dat[i * components + 2];
            dat[i * components + 2] = tmp;
        }

        dat += image.getRowSpan();
    }

    // load the resulting image into the texture
    result->loadFromMemory(image.getData(),
                           Size(image.getWidth(),
                                image.getHeight()),
                           format);

    return result;
}
void 
MaterialPreviewDialog::buildPreviewBitmap( const Ogre::String &texName )
{
	const Ogre::uchar BytePerPixel = 8;

	// 读取原始image
	Ogre::Image *oriImage = getPreviewImage(texName);
	// 源大纹理的大小
	size_t oriImageHeight = oriImage->getHeight();
	size_t oriImageWidth = oriImage->getWidth();

	Ogre::uchar *oriImageData = oriImage->getData();

	// 分配一个足够大的空间来保存新建的image的数据
	size_t newImagegetRowSpan = oriImageWidth*oriImage->getBPP()/BytePerPixel;  // 新建的image的行宽(单位为字节)
	Ogre::uchar *newImageData = new Ogre::uchar[oriImageHeight*newImagegetRowSpan];

	Ogre::uchar *newImageDataPointer = newImageData;

	Ogre::uchar *oriImagedataPointer = oriImageData;

	// 把所选的纹理的数据提取出来,并创建一个新的image
	for ( Ogre::uint i=0; i<oriImageHeight; ++i )
	{
		memcpy(newImageDataPointer, oriImagedataPointer, newImagegetRowSpan);
		newImageDataPointer += newImagegetRowSpan;
		oriImagedataPointer += oriImage->getRowSpan();
	}

	Ogre::Image newImage;
	newImage.loadDynamicImage(newImageData,oriImageWidth,oriImageHeight,1,oriImage->getFormat(),true);

	// 如果所选纹理大于64*64,就先resize
	if ( oriImageWidth > mPreviewImageWidth || oriImageHeight > mPreviewImageHeight )
		newImage.resize(mPreviewImageWidth, mPreviewImageHeight);

	// 如果有alpha,要与黑白图进行混合
	if ( newImage.getHasAlpha() )
	{
		Ogre::uchar *tempPtr = newImage.getData();

		assert (tempPtr);

		for ( size_t i=0; i<mPreviewImageHeight; ++i )
			for ( size_t j=0; j<mPreviewImageWidth; ++j )
			{
				// 取出alpha值
				float alphaValue = (float)tempPtr[3] / 255.0f;

				// 计算出经过alpha混合后的颜色值
				unsigned char r = tempPtr[2] * alphaValue;
				unsigned char g = tempPtr[1] * alphaValue;
				unsigned char b = tempPtr[0] * alphaValue;

				// 设置到image中
				mCurrentPreviewImage.SetRGB(j,i,r,g,b);
				tempPtr += 4;
			}

			// 要把指针移回到图片数据的
			tempPtr -= mPreviewImageHeight * mPreviewImageWidth * 4;
			// 设置到缩略图控件中
	}
	// 没有alpha,就直接拷贝数据
	else
	{
		memcpy ( mCurrentPreviewImage.GetData(), newImage.getData(), newImage.getSize() );
	}
}
Example #3
0
void 
BrushSelector::buildPreviewBitmap( const Fairy::TextureInfo texInfo )
{
    const Ogre::uchar BytePerPixel = 8;

    // 读取原始image
    Ogre::Image *oriImage = GetSceneManipulator()->getPreviewImage(texInfo.ownerTextureName);
    // 源大纹理的大小
    size_t oriImageHeight = oriImage->getHeight();
    size_t oriImageWidth = oriImage->getWidth();

    Ogre::uchar *oriImageData = oriImage->getData();
    // 所选纹理的大小
    size_t newImageWidth = texInfo.width*TexTileSize;
    size_t newImageHeight = texInfo.height*TexTileSize;

    // 分配一个足够大的空间来保存新建的image的数据
    size_t newImagegetRowSpan = newImageWidth*oriImage->getBPP()/BytePerPixel;  // 新建的image的行宽(单位为字节)
    Ogre::uchar *newImageData = OGRE_ALLOC_T(Ogre::uchar, oriImageHeight*newImagegetRowSpan, Ogre::MEMCATEGORY_GENERAL);//new Ogre::uchar[newImageHeight*newImagegetRowSpan];
    
    Ogre::uchar *newImageDataPointer = newImageData;
    // 得知起始像素点
    size_t startPoint = ( oriImageWidth * texInfo.topCorner + texInfo.leftCorner )
        * TexTileSize * oriImage->getBPP()/BytePerPixel;

    Ogre::uchar *oriImagedataPointer = oriImageData + startPoint;

    // 把所选的纹理的数据提取出来,并创建一个新的image
    for ( Ogre::uint i=0; i<newImageHeight; ++i )
    {
        memcpy(newImageDataPointer, oriImagedataPointer, newImagegetRowSpan);
        newImageDataPointer += newImagegetRowSpan;
        oriImagedataPointer += oriImage->getRowSpan();
    }

    Ogre::Image newImage;
    newImage.loadDynamicImage(newImageData,newImageWidth,newImageHeight,1,oriImage->getFormat(),true);

    // 如果所选纹理大于64*64,就先resize
    if ( texInfo.width > 1 || texInfo.height > 1 )
        newImage.resize(mPreviewImageWidth, mPreviewImageHeight);

    // 如果有alpha,要与黑白图进行混合
    if ( newImage.getHasAlpha() )
    {  
		Ogre::ColourValue col;

		for ( int i=0; i<mPreviewImageWidth; ++i )
		{
			for ( int j=0; j<mPreviewImageWidth; ++j )
			{
				col = newImage.getColourAt(j,i,0);

				float alphaValue = col.a;

				unsigned char r = col.r*255 * alphaValue + mBlackWhitePreviewImage.GetRed(i,j) * ( 1.0f - alphaValue);
				unsigned char g = col.g*255 * alphaValue + mBlackWhitePreviewImage.GetGreen(i,j) * ( 1.0f - alphaValue);
				unsigned char b = col.b*255 * alphaValue + mBlackWhitePreviewImage.GetBlue(i,j) * ( 1.0f - alphaValue);

				// 设置到image中
				mCurrentPreviewImage.SetRGB(j,i,r,g,b);
			}
		}
        // 设置到缩略图控件中
        mBrushesPreview->SetBitmap(mCurrentPreviewImage);
    }
    // 没有alpha,就直接拷贝数据
    else
    {
		Ogre::ColourValue col;

		for ( int i=0; i<mPreviewImageWidth; ++i )
		{
			for ( int j=0; j<mPreviewImageWidth; ++j )
			{
				col = newImage.getColourAt(j,i,0);

				unsigned char r = col.r*255;
				unsigned char g = col.g*255;
				unsigned char b = col.b*255;

				// 设置到image中
				mCurrentPreviewImage.SetRGB(j,i,r,g,b);
			}
		}

        mBrushesPreview->SetBitmap(mCurrentPreviewImage);    
    }
}
void 
MaterialPreviewDialog::buildPreviewBitmap( const Ogre::String &texName )
{
	const Ogre::uchar BytePerPixel = 8;

	// 读取原始image
	Ogre::Image *oriImage = getPreviewImage(texName);
	// 源大纹理的大小
	size_t oriImageHeight = oriImage->getHeight();
	size_t oriImageWidth = oriImage->getWidth();

	Ogre::uchar *oriImageData = oriImage->getData();

	// 分配一个足够大的空间来保存新建的image的数据
	size_t newImagegetRowSpan = oriImageWidth*oriImage->getBPP()/BytePerPixel;  // 新建的image的行宽(单位为字节)
	Ogre::uchar *newImageData = OGRE_ALLOC_T(Ogre::uchar, oriImageHeight*newImagegetRowSpan, Ogre::MEMCATEGORY_GENERAL);//new Ogre::uchar[oriImageHeight*newImagegetRowSpan];

	Ogre::uchar *newImageDataPointer = newImageData;

	Ogre::uchar *oriImagedataPointer = oriImageData;

	// 把所选的纹理的数据提取出来,并创建一个新的image
	for ( Ogre::uint i=0; i<oriImageHeight; ++i )
	{
		memcpy(newImageDataPointer, oriImagedataPointer, newImagegetRowSpan);
		newImageDataPointer += newImagegetRowSpan;
		oriImagedataPointer += oriImage->getRowSpan();
	}

	Ogre::Image newImage;
	newImage.loadDynamicImage(newImageData,oriImageWidth,oriImageHeight,1,oriImage->getFormat(),true);

	// 如果所选纹理大于64*64,就先resize
	if ( oriImageWidth > mPreviewImageWidth || oriImageHeight > mPreviewImageHeight )
		newImage.resize(mPreviewImageWidth, mPreviewImageHeight);

	// 如果有alpha,要与黑白图进行混合
	if ( newImage.getHasAlpha() )
	{
		Ogre::ColourValue col;

		for ( int i=0; i<mPreviewImageWidth; ++i )
		{
			for ( int j=0; j<mPreviewImageWidth; ++j )
			{
				col = newImage.getColourAt(j,i,0);

				float alphaValue = col.a;

				unsigned char r = col.r*255 * alphaValue; 
				unsigned char g = col.g*255 * alphaValue; 
				unsigned char b = col.b*255 * alphaValue;

				// 设置到image中
				mCurrentPreviewImage.SetRGB(j,i,r,g,b);
			}
		}
	}
	// 没有alpha,就直接拷贝数据
	else
	{
		Ogre::ColourValue col;

		for ( int i=0; i<mPreviewImageWidth; ++i )
		{
			for ( int j=0; j<mPreviewImageWidth; ++j )
			{
				col = newImage.getColourAt(j,i,0);

				unsigned char r = col.r*255;
				unsigned char g = col.g*255;
				unsigned char b = col.b*255;

				// 设置到image中
				mCurrentPreviewImage.SetRGB(j,i,r,g,b);
			}
		}
	}
}