// --------------------------------------------------------------------------- void CBuilderZone::snapshotCustom (const char *fileName, uint width, uint height, bool keepRatio, uint sizeSource, bool grayscale) { if (_ZoneRegions.size() == 0) return; // Some bitmaps NLMISC::CBitmap bitmapTmp; NLMISC::CBitmap bitmapDest; const CZoneRegion *pBZR = &(getDocument ()->getZoneRegion (_ZoneRegionSelected)); sint32 nMinX = pBZR->getMinX(); sint32 nMaxX = pBZR->getMaxX(); sint32 nMinY = pBZR->getMinY(); sint32 nMaxY = pBZR->getMaxY(); uint nSizeX = (nMaxX - nMinX + 1)*sizeSource; uint nSizeY = (nMaxY - nMinY + 1)*sizeSource; sint x, y, j; // Keep ratio ? if (keepRatio) height = (width * nSizeY) / nSizeX; // Resize the bitmaps bitmapDest.resize (nSizeX, nSizeY, NLMISC::CBitmap::RGBA); // white all NLMISC::CObjectVector<uint8> &rPixels = bitmapDest.getPixels(); memset (&rPixels[0], 0xff, rPixels.size ()); // Copy ZoneBitmaps in the bitmap CUV uvMin, uvMax; ITexture *pTexture; CZoneBankElement *pZBE; uint8 nRot, nFlip; // For each tiles for (y = nMinY; y <= nMaxY; ++y) for (x = nMinX; x <= nMaxX; ++x) { const string &rsZoneName = pBZR->getName (x, y); if ((rsZoneName == STRING_OUT_OF_BOUND) && (rsZoneName == STRING_UNUSED)) continue; pZBE = _ZoneBank.getElementByZoneName (rsZoneName); if (pZBE == NULL) continue; // Get the texture pTexture = _DataBase.getTexture (rsZoneName, pBZR->getPosX(x, y), pBZR->getPosY(x, y), uvMin, uvMax); // Generate it pTexture->generate (); // Be sure it is tga pTexture->convertToType (NLMISC::CBitmap::RGBA); // Get rot nRot = pBZR->getRot(x, y); // Get flip nFlip = pBZR->getFlip(x, y); // Copy the texture // Dest bitmap size uint destWidth = 1+(uint)((float)pTexture->getWidth() * (uvMax.U - uvMin.U)); uint destHeight = 1+(uint)((float)pTexture->getHeight() * (uvMax.V - uvMin.V)); bitmapTmp.resize (destWidth, destHeight, NLMISC::CBitmap::RGBA); // Source bitmap size and position uint u = (uint)((float)pTexture->getWidth() * uvMin.U); uint v = (uint)((float)pTexture->getHeight() * uvMin.V); uint sourceWidth = pTexture->getWidth(); uint sourceHeight = pTexture->getHeight(); // Source pointer uint8 *srcPixels = &(pTexture->getPixels ()[0]); // Destination pointer uint8 *destPixels = &(bitmapTmp.getPixels ()[0]); // Copy the temp bitmap for (j = 0; j < (sint)destHeight; ++j) // Copy the line memcpy (destPixels+(4*j*destWidth), srcPixels + 4 * ( (v + j) * sourceWidth + u), destWidth*4); // Flip ? if (nFlip) bitmapTmp.flipH(); // Rot ? while (nRot) { bitmapTmp.rot90CW (); nRot--; } // Resize the bitmap to normal size if ( (bitmapTmp.getWidth () != sizeSource) || (bitmapTmp.getHeight () != sizeSource) ) bitmapTmp.resample (sizeSource, sizeSource); // Copy it in the map bitmapDest.blit (&bitmapTmp, (x-nMinX)*sizeSource, (y-nMinY)*sizeSource); pTexture->release (); } // Resample the final bitmap bitmapDest.resample (width, height); bitmapDest.flipV (); COFile f(fileName, false, false, true); if (grayscale) { bitmapDest.convertToType (NLMISC::CBitmap::Luminance); if (bitmapDest.writeTGA (f, 8)) f.close(); } else { if (bitmapDest.writeTGA (f, 32)) f.close(); } }
// --------------------------------------------------------------------------- bool CDataBase::init (const string &Path, CZoneBank &zb) { string sDirBackup = NLMISC::CPath::getCurrentPath(); // "Path" can be relative to the doc path so we have to be first in the doc path string s2 = NLMISC::CFile::getPath ((LPCTSTR)getMainFrame()->getDocument()->GetPathName()); NLMISC::CPath::setCurrentPath(s2.c_str()); string ss = NLMISC::CPath::getFullPath(Path); NLMISC::CPath::setCurrentPath (ss.c_str()); uint32 i, m, n, o, p; uint8 k, l; vector<string> ZoneNames; zb.getCategoryValues ("zone", ZoneNames); for (i = 0; i < ZoneNames.size(); ++i) { // Progress getMainFrame ()->progressLoadingDialog ((float)i / (float)ZoneNames.size()); SElement zdbTmp; CZoneBankElement *pZBE = zb.getElementByZoneName (ZoneNames[i]); // Read the texture file string zdbTmpName = ZoneNames[i]; zdbTmp.SizeX = pZBE->getSizeX (); zdbTmp.SizeY = pZBE->getSizeY (); const vector<bool> &rMask = pZBE->getMask(); NLMISC::CBitmap *pBitmap = loadBitmap (getTextureFile(zdbTmpName)); // Should not return NULL ! nlassert (pBitmap); // Wanted zone size uint width = _RefSizeX * zdbTmp.SizeX; uint height = _RefSizeY * zdbTmp.SizeY; // Good size ? if ((pBitmap->getWidth () != width) || (pBitmap->getHeight () != height)) { // Resize it pBitmap->resample (width, height); } zdbTmp.WinBitmap = convertToWin (pBitmap); pBitmap->flipV (); for (l = 0; l < zdbTmp.SizeY; ++l) for (k = 0; k < zdbTmp.SizeX; ++k) if (rMask[k+l*zdbTmp.SizeX]) { SCacheZone czTmp; czTmp.PosX = k; czTmp.PosY = l; // Found first non full texture cache for (m = 0; m < 64; ++m) if (_CacheTexture[m].Enabled == false) { // Create the texture _CacheTexture[m].FreePlace.resize (_RefCacheTextureNbEltX*_RefCacheTextureNbEltY, true); _CacheTexture[m].Texture = new CTextureMem(); _CacheTexture[m].Texture->setAllowDegradation (true); _CacheTexture[m].PtrMem.resize (4*_RefCacheTextureSizeX*_RefCacheTextureSizeY); _CacheTexture[m].Texture->resize (_RefCacheTextureSizeX, _RefCacheTextureSizeY); _CacheTexture[m].Texture->setPointer (&_CacheTexture[m].PtrMem[0], 4*_RefCacheTextureSizeX*_RefCacheTextureSizeY, false, false, _RefCacheTextureSizeX, _RefCacheTextureSizeY); _CacheTexture[m].Enabled = true; break; } else { if (!_CacheTexture[m].isFull()) break; } nlassert (m<64); // Found first place in this texture for (n = 0; n < _CacheTexture[m].FreePlace.size(); ++n) if (_CacheTexture[m].FreePlace[n]) { sint32 xSrc = k*_RefSizeX; sint32 ySrc = l*_RefSizeY; sint32 xDst = (n%_RefCacheTextureNbEltX)*_RefSizeX; sint32 yDst = (n/_RefCacheTextureNbEltX)*_RefSizeY; uint8 *pSrc = &pBitmap->getPixels()[(xSrc+ySrc*pBitmap->getWidth())*4]; uint8 *pDst = &_CacheTexture[m].PtrMem[(xDst+yDst*_RefCacheTextureSizeX)*4]; // Copy part of the bitmap into cache texture for (p = 0; p < _RefSizeY; ++p) for (o = 0; o < _RefSizeX; ++o) { pDst[(o+p*_RefCacheTextureSizeX)*4+0] = pSrc[(o+p*pBitmap->getWidth())*4+0]; pDst[(o+p*_RefCacheTextureSizeX)*4+1] = pSrc[(o+p*pBitmap->getWidth())*4+1]; pDst[(o+p*_RefCacheTextureSizeX)*4+2] = pSrc[(o+p*pBitmap->getWidth())*4+2]; pDst[(o+p*_RefCacheTextureSizeX)*4+3] = pSrc[(o+p*pBitmap->getWidth())*4+3]; } czTmp.PosUV.U = ((float)xDst) / ((float)_RefCacheTextureSizeX); czTmp.PosUV.V = ((float)yDst) / ((float)_RefCacheTextureSizeY); czTmp.CacheTexture = _CacheTexture[m].Texture; _CacheTexture[m].FreePlace[n] = false; break; } //nlassert (m<_CacheTexture[m].FreePlace.size()); zdbTmp.ZonePieces.push_back (czTmp); } // Add the entry in the DataBase _ZoneDBmap.insert (pair<string,SElement>(zdbTmpName, zdbTmp)); delete pBitmap; } // Upload all textures in VRAM for (m = 0; m < 64; ++m) if (_CacheTexture[m].Enabled) _CacheTexture[m].Texture->touch (); _UnusedTexture = loadTexture (getTextureFile("_UNUSED_")); NLMISC::CPath::setCurrentPath(sDirBackup); return true; }