//----------------------------------------------------------------------------// 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() ); } }
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); } } } }