void rbWindow::setIcon(unsigned int width, unsigned int height, const std::vector<rb::Value>& pixels) { std::vector<sf::Uint8> convPixels(pixels.size(), 0); for(int index = 0, size = pixels.size(); index < size; index++) { convPixels[index] = pixels[index].to<int>(); } getWindow()->setIcon(width, height, convPixels.data()); }
//------------------------------------------------------ void TextureAtlas::build() { if (!mIsDirty) return; bool fitted; size_t area = 0; // build the fonts (if this didn't happen already) // so we'll be sure the glyphs are there to be atlassed FontSet::iterator fit = mMyFonts.begin(); while (fit != mMyFonts.end()) { FontDrawSource* fdsp = *fit++; if (!fdsp->isBuilt()) fdsp->build(); } // First, we sort by size of the DrawSource mMyDrawSources.sort(DrawSourceLess()); // now try to allocate all the draw sources. If we fail, grow and try again do { fitted = true; area = 0; // try to fit DrawSourceList::iterator it = mMyDrawSources.begin(); while (it != mMyDrawSources.end()) { const DrawSourcePtr& ds = *it++; const PixelSize& ps = ds->getPixelSize(); area += ps.getPixelArea(); LOG_VERBOSE("TextureAtlas: (%s) Trying to place %d x %d (%d -> %d)", mAtlasName.c_str(), ps.width, ps.height, ps.getPixelArea(), area); // try to allocate FreeSpaceInfo* fsi = mAtlasAllocation->allocate(ps.width, ps.height); if (fsi) { ds->setPlacementPtr(fsi); } else { fitted = false; break; } } // fitted? if (!fitted) // nope - Enlarge! enlarge(area); } while (!fitted); LOG_INFO("TextureAtlas: (%s) Creating atlas with dimensions %d x %d", mAtlasName.c_str(), mAtlasSize.width, mAtlasSize.height); if (mTexture.isNull()) prepareResources(); // TODO: Reallocate the texture here if needed! Ogre::HardwarePixelBufferSharedPtr pixelBuffer = mTexture->getBuffer(); pixelBuffer->lock(Ogre::HardwareBuffer::HBL_DISCARD); const Ogre::PixelBox& targetBox = pixelBuffer->getCurrentLock(); size_t pixelsize = Ogre::PixelUtil::getNumElemBytes(targetBox.format); size_t rowsize = targetBox.rowPitch * pixelsize; Ogre::uint8* dstData = static_cast<Ogre::uint8*>(targetBox.data); // We'll iterate over all draw sources, painting the pixels onto the allocated space DrawSourceList::iterator it = mMyDrawSources.begin(); while (it != mMyDrawSources.end()) { const DrawSourcePtr& ds = *it++; // render all pixels into the right place FreeSpaceInfo* fsi = reinterpret_cast<FreeSpaceInfo*>(ds->getPlacementPtr()); assert(fsi); // render into the specified place unsigned char* conversionBuf = NULL; const PixelSize& dps = ds->getPixelSize(); Ogre::Image* img = ds->getImage(); Ogre::PixelBox srcPixels = img->getPixelBox(); // convert if the source data don't match if(img->getFormat() != Ogre::PF_BYTE_BGRA) { conversionBuf = new unsigned char[img->getWidth() * img->getHeight() * pixelsize]; Ogre::PixelBox convPixels(Ogre::Box(0, 0, dps.width, dps.height), Ogre::PF_BYTE_BGRA, conversionBuf); Ogre::PixelUtil::bulkPixelConversion(srcPixels, convPixels); srcPixels = convPixels; } size_t srcrowsize = srcPixels.rowPitch * pixelsize; Ogre::uint8* srcData = static_cast<Ogre::uint8*>(srcPixels.data); // TODO: we're always handling 32bit data, so we could as well transfer 4 bytes each iteration instead of one (speedup) for(size_t row = 0; row < dps.height; row++) { for(size_t col = 0; col < srcrowsize; col++) { dstData[((row + fsi->y) * rowsize) + (fsi->x * pixelsize) + col] = srcData[(row * srcrowsize) + col]; } } delete[] conversionBuf; // Convert the full draw source pixel coordinates to the atlas contained ones (initializes the texturing coordinates transform) ds->atlas(mMaterial, fsi->x, fsi->y, mAtlasSize.width, mAtlasSize.height); } // for debug, write the texture to a file /*unsigned char *readrefdata = static_cast<unsigned char*>(targetBox.data); Ogre::Image img; img = img.loadDynamicImage (readrefdata, mTexture->getWidth(), mTexture->getHeight(), mTexture->getFormat()); img.save(mAtlasName + ".png");*/ // and close the pixel buffer of the atlas at the end pixelBuffer->unlock(); mIsDirty = false; }