Esempio n. 1
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 = 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() );
	}
}
Esempio n. 3
0
void
Terrain::_createAtlasPixmap(size_t pixmapId)
{
    const TerrainData::Pixmap& pixmap = mData->mPixmaps[pixmapId];
    size_t textureId = pixmap.textureId;
    assert(textureId < mData->mTextures.size());
    const Ogre::String& textureName = mData->mTextures[textureId];

    // If the atlas texture already exist, use it.

    AtlasArray::const_iterator it;
    for (it = mAtlases.begin(); it != mAtlases.end(); ++it)
    {
        if (it->texture->getName() == textureName)
            break;
    }
    if (it != mAtlases.end())
    {
        // Fill up atlas pixmap info
        size_t atlasId = it - mAtlases.begin() + 1;
        mAtlasPixmaps[pixmapId].atlasId = atlasId;
        mAtlasPixmaps[pixmapId].left = pixmap.left;
        mAtlasPixmaps[pixmapId].top = pixmap.top;
        mAtlasPixmaps[pixmapId].right = pixmap.right;
        mAtlasPixmaps[pixmapId].bottom = pixmap.bottom;
        return;
    }

    // If texture already loaded and is composited, use it without any modify.
    Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().getByName(textureName);
    if (!texture.isNull() &&
        (texture->getWidth() > mAtlasPixmapSize || texture->getHeight() > mAtlasPixmapSize))
    {
        mAtlases.push_back(Atlas());
        Atlas& atlas = mAtlases.back();

        atlas.texture = texture;

        // Fill up atlas pixmap info
        size_t atlasId = mAtlases.size();
        mAtlasPixmaps[pixmapId].atlasId = atlasId;
        mAtlasPixmaps[pixmapId].left = pixmap.left;
        mAtlasPixmaps[pixmapId].top = pixmap.top;
        mAtlasPixmaps[pixmapId].right = pixmap.right;
        mAtlasPixmaps[pixmapId].bottom = pixmap.bottom;
        return;
    }

    // Load the image
    Ogre::Image image;
    image.load(textureName, BRUSH_RESOURCE_GROUP_NAME);

    // If the image is composited, use it without any modify.
    if (image.getWidth() > mAtlasPixmapSize || image.getHeight() > mAtlasPixmapSize)
    {
        mAtlases.push_back(Atlas());
        Atlas& atlas = mAtlases.back();

        // re-use the loaded image avoid load it again
        atlas.texture =
            Ogre::TextureManager::getSingleton()
            .loadImage(textureName, BRUSH_RESOURCE_GROUP_NAME, image);

        // Fill up atlas pixmap info
        size_t atlasId = mAtlases.size();
        mAtlasPixmaps[pixmapId].atlasId = atlasId;
        mAtlasPixmaps[pixmapId].left = pixmap.left;
        mAtlasPixmaps[pixmapId].top = pixmap.top;
        mAtlasPixmaps[pixmapId].right = pixmap.right;
        mAtlasPixmaps[pixmapId].bottom = pixmap.bottom;
        return;
    }

    // Composite into the atlas texture.

    bool isTransparent = image.getHasAlpha();
    AtlasAllocInfo& allocInfo = isTransparent ? mTransparentAtlasAllocInfo : mSolidAtlasAllocInfo;
    if (allocInfo.blockId >= mMaxAtlasBlockId)
    {
        // Use special name to avoid confuse with other reference with this texture
       Ogre::String atlasName = "<Terrain/Atlas>:" + Ogre::StringConverter::toString(mAtlases.size());

        mAtlases.push_back(Atlas());
        Atlas& atlas = mAtlases.back();

        Ogre::PixelFormat pixelFormat = isTransparent ? Ogre::PF_A8R8G8B8 : Ogre::PF_X8R8G8B8;
        atlas.image.bind(new Ogre::Image);
        atlas.image->loadDynamicImage(0, mAtlasTextureSize, mAtlasTextureSize, 1, pixelFormat, true, 1, mAtlasNumMipMaps);
        memset(atlas.image->getData(), 0, atlas.image->getSize());

        atlas.texture =
            Ogre::TextureManager::getSingleton().createManual(atlasName,
                BRUSH_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D,
                atlas.image->getWidth(), atlas.image->getHeight(),
                mAtlasNumMipMaps, atlas.image->getFormat(),
                Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE,
                this);

        allocInfo.atlasId = mAtlases.size();
        allocInfo.blockId = 0;
    }

    // Copy origin pixmap to atlas image
    Atlas& atlas = mAtlases[allocInfo.atlasId - 1];
    int blockX = allocInfo.blockId % mAtlasBlockSize;
    int blockY = allocInfo.blockId / mAtlasBlockSize;
    Ogre::PixelBox dst = atlas.image->getPixelBox().getSubVolume(Ogre::Box(
        blockX * mAtlasPixmapSize,
        blockY * mAtlasPixmapSize,
        blockX * mAtlasPixmapSize + mAtlasPixmapSize,
        blockY * mAtlasPixmapSize + mAtlasPixmapSize));
    Ogre::PixelBox src = image.getPixelBox().getSubVolume(Ogre::Box(
        fast_ifloor(pixmap.left * image.getWidth() + 0.5f),
        fast_ifloor(pixmap.top * image.getHeight() + 0.5f),
        fast_ifloor(pixmap.right * image.getWidth() + 0.5f),
        fast_ifloor(pixmap.bottom * image.getHeight() + 0.5f)));
    if (src.getWidth() == mAtlasPixmapSize && src.getHeight() == mAtlasPixmapSize)
        Ogre::PixelUtil::bulkPixelConversion(src, dst);
    else
        Ogre::Image::scale(src, dst);

    // Generate mipmaps manual
    for (size_t mipmap = 1; mipmap <= mAtlasNumMipMaps; ++mipmap)
    {
        src = dst;
        size_t pixmapSize = mAtlasPixmapSize >> mipmap;
        dst = atlas.image->getPixelBox(0, mipmap).getSubVolume(Ogre::Box(
            blockX * pixmapSize,
            blockY * pixmapSize,
            blockX * pixmapSize + pixmapSize,
            blockY * pixmapSize + pixmapSize));
        Ogre::Image::scale(src, dst);
    }

    // Notify that the atlas texture need to reload
    if (atlas.texture->isLoaded())
        atlas.texture->unload();

    ++allocInfo.blockId;

    // Fill up atlas pixmap info

    mAtlasPixmaps[pixmapId].atlasId = allocInfo.atlasId;
    mAtlasPixmaps[pixmapId].left = blockX * mAtlasBlockTexCoordInc + 0.5f / mAtlasTextureSize;
    mAtlasPixmaps[pixmapId].top = blockY * mAtlasBlockTexCoordInc + 0.5f / mAtlasTextureSize;
    mAtlasPixmaps[pixmapId].right = mAtlasPixmaps[pixmapId].left + mAtlasBlockTexCoordInc -  1.0f / mAtlasTextureSize;
    mAtlasPixmaps[pixmapId].bottom = mAtlasPixmaps[pixmapId].top + mAtlasBlockTexCoordInc -  1.0f / mAtlasTextureSize;
}
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);
			}
		}
	}
}