// *************************************************************************** void CMovieShooter::getFrameData(CFrameHeader *frame, NLMISC::CBitmap &bmp) { uint w= frame->Width; uint h= frame->Height; // resize if(bmp.getWidth()!=w || bmp.getHeight()!=h) bmp.resize(w, h); // unpack. uint16 *src= (uint16*)frame->Data; CRGBA *dst= (CRGBA*)&bmp.getPixels()[0]; for(uint npix= w*h; npix>0; npix--, src++, dst++) { dst->set565(*src); } }
void CIconWnd::modulateIcon(NLMISC::CBitmap &dst, const NLMISC::CRGBA &col) { // modulate an icon by a color CObjectVector<uint8> &data = dst.getPixels(); for (uint y=0 ; y<dst.getHeight() ; y++) { for (uint x=0 ; x<dst.getWidth() ; x++) { CRGBA c; c.modulateFromColor(col, dst.getPixelColor(x, y)); data[(x+y*dst.getWidth())*4] = c.R; data[(x+y*dst.getWidth())*4+1] = c.G; data[(x+y*dst.getWidth())*4+2] = c.B; data[(x+y*dst.getWidth())*4+3] = dst.getPixelColor(x, y).A; } } }
void CIconWnd::blendIcons(NLMISC::CBitmap &dst, const NLMISC::CBitmap &src) { // blend between two icons nlassert(dst.getWidth() == src.getWidth()); nlassert(dst.getHeight() == src.getHeight()); CObjectVector<uint8> &data = dst.getPixels(); for (uint y=0 ; y<dst.getHeight() ; y++) { for (uint x=0 ; x<dst.getWidth() ; x++) { CRGBA c; c.blendFromui(dst.getPixelColor(x, y), src.getPixelColor(x, y), src.getPixelColor(x, y).A); data[(x+y*dst.getWidth())*4] = c.R; data[(x+y*dst.getWidth())*4+1] = c.G; data[(x+y*dst.getWidth())*4+2] = c.B; data[(x+y*dst.getWidth())*4+3] = c.A; } } }
void Browse::OnImportBorder() { // Select a file CFileDialog sFile (true, NULL, NULL, OFN_ENABLESIZING, "Targa bitmap (*.tga)|*.tga|All files (*.*)|*.*||",NULL); if (sFile.DoModal()==IDOK) { // Get the border of the bank std::vector<NLMISC::CBGRA> array(128*128); // The bitmap NLMISC::CBitmap bitmap; // Read the bitmap bool error=false; CString pathName=sFile.GetPathName(); try { CIFile file; if (file.open ((const char*)pathName)) { // Export bitmap.load (file); } else error=true; } catch (Exception& e) { const char *toto=e.what (); error=true; } // Error during import ? if (error) { // Error message char tmp[512]; sprintf (tmp, "Can't read bitmap %s", (const char*)pathName); MessageBox (tmp, "Import border", MB_OK|MB_ICONEXCLAMATION); } // Get pixel CRGBA *pPixel=(CRGBA*)&bitmap.getPixels()[0]; // Good size if ((bitmap.getWidth()==128)&&(bitmap.getHeight()==128)) { // Make a copy for (int i=0; i<128*128; i++) { // Copy the pixel array[i].R=pPixel->R; array[i].G=pPixel->G; array[i].B=pPixel->B; array[i].A=pPixel->A; pPixel++; } } else { // Error message char tmp[512]; sprintf (tmp, "The bitmap must have a size of 128x128 (%s)", (const char*)pathName); MessageBox (tmp, "Import border", MB_OK|MB_ICONEXCLAMATION); } // 256 or 128 ? CTileBorder border; border.set (128, 128, array); tileBank2.getTileSet (land)->setBorder (m_ctrl.Texture==1?CTile::diffuse:CTile::additive, border); // Message MessageBox ("The border has been changed.", "Import border", MB_OK|MB_ICONINFORMATION); } }
void Browse::OnExportBorder() { // Select a file CFileDialog sFile (false, NULL, NULL, OFN_ENABLESIZING, "Targa bitmap (*.tga)|*.tga|All files (*.*)|*.*||",NULL); if (sFile.DoModal()==IDOK) { // Get the border of the bank std::vector<NLMISC::CBGRA> array; // 256 or 128 ? int width, height; tileBank2.getTileSet (land)->getBorder128 (m_ctrl.Texture==1?CTile::diffuse:CTile::additive)->get (width, height, array); // Make a bitmap if (width&&height) { NLMISC::CBitmap bitmap; bitmap.resize (width, height, NLMISC::CBitmap::RGBA); // Get pixel CRGBA *pPixel=(CRGBA*)&bitmap.getPixels()[0]; // Make a copy for (int i=0; i<width*height; i++) { // Copy the pixel pPixel->R=array[i].R; pPixel->G=array[i].G; pPixel->B=array[i].B; pPixel->A=array[i].A; pPixel++; } // Write the bitmap bool error=false; CString pathName=sFile.GetPathName(); try { COFile file; if (file.open ((const char*)pathName)) { // Export bitmap.writeTGA (file, 32); } else error=true; } catch (Exception& e) { const char *toto=e.what (); error=true; } // Error during export ? if (error) { // Error message char tmp[512]; sprintf (tmp, "Can't write bitmap %s", (const char*)pathName); MessageBox (tmp, "Export border", MB_OK|MB_ICONEXCLAMATION); } } } }
// --------------------------------------------------------------------------- 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; }
// ************************************************************************************* void CDriverD3D::addCursor(const std::string &name, const NLMISC::CBitmap &cursorBitmap) { if (!isAlphaBlendedCursorSupported()) return; nlassert(cursorBitmap.getWidth() != 0); nlassert(cursorBitmap.getHeight() != 0); // find used part base on alpha, to avoid too much shrinking const CRGBA *pixels = (const CRGBA *) &cursorBitmap.getPixels()[0]; uint minX, maxX, minY, maxY; uint width = cursorBitmap.getWidth(); uint height = cursorBitmap.getHeight(); // minX = 0; for (uint x = 0; x < width; ++x) { bool stop = false; minX = x; for (uint y = 0; y < height; ++y) { if(pixels[x + y * width].A != 0) { stop = true; break; } } if (stop) break; } // maxX = width - 1; for (sint x = width - 1; x >= 0; --x) { bool stop = false; maxX = (uint) x; for (uint y = 0; y < height; ++y) { if(pixels[x + y * width].A != 0) { stop = true; break; } } if (stop) break; } // minY = 0; for (uint y = 0; y < height; ++y) { bool stop = false; minY = y; for (uint x = 0; x < width; ++x) { if(pixels[x + y * width].A != 0) { stop = true; break; } } if (stop) break; } // maxY = height - 1; for (sint y = height - 1; y >= 0; --y) { bool stop = false; maxY = (uint) y; for (uint x = 0; x < width; ++x) { if(pixels[x + y * width].A != 0) { stop = true; break; } } if (stop) break; } // CCursor &curs = _Cursors[name]; curs = CCursor(); // erase possible previous cursor uint destWidth = GetSystemMetrics(SM_CXCURSOR); uint destHeight = GetSystemMetrics(SM_CYCURSOR); // build a square bitmap uint tmpSize = std::max(maxX - minX + 1, maxY - minY + 1); curs.Src.resize(tmpSize, tmpSize); // blit at top left corner curs.Src.blit(cursorBitmap, minX, minY, maxX - minX + 1, maxY - minY + 1, 0, 0); curs.OrigHeight = cursorBitmap.getHeight(); curs.HotspotOffsetX = minX; curs.HotspotOffsetY = minY; // curs.HotspotScale = _CursorScale; clamp(curs.HotspotScale, 0.f, 1.f); // first resampling, same for all cursors tmpSize = (uint) (tmpSize * curs.HotspotScale); if (tmpSize == 0) tmpSize = 1; if (curs.HotspotScale < 1.f) { curs.Src.resample(tmpSize, tmpSize); } // shrink if necessary if (tmpSize > destWidth || tmpSize > destHeight) // need to shrink ? { // constraint proportions curs.HotspotScale *= std::min(float(destWidth) / tmpSize, float(destHeight) / tmpSize); curs.Src.resample(destWidth, destHeight); } else { CBitmap final; final.resize(destWidth, destHeight); final.blit(&curs.Src, 0, 0);
//TODO titegus: What's the point in Importing a new border if there is no Pixel Compatibility check ? void CTile_browser_dlg::on_importBorderPushButton_clicked() { QFileDialog::Options options; QString selectedFilter; QString fileName = QFileDialog::getOpenFileName(this, tr("Choose Bitmap"), QString(tileBankBrowser.getAbsPath().c_str()) , "Targa Bitmap(*.tga);;All Files (*.*);;", &selectedFilter, options); if (!fileName.isEmpty()) { fileName = QDir::toNativeSeparators(fileName); // Get the border of the bank std::vector<NLMISC::CBGRA> array(128*128); // The bitmap NLMISC::CBitmap bitmap; // Read the bitmap bool error=false; try { CIFile file; if (file.open (fileName.toStdString().c_str())) { // Export bitmap.load (file); } else error=true; } catch (Exception& e) { const char *toto=e.what (); error=true; } // Error during import ? if (error) { // Error message QString s = tr("Can't read bitmap %1").arg(fileName); QMessageBox::information (this, tr("Import border"), s); } // Get pixel CRGBA *pPixel=(CRGBA*)&bitmap.getPixels()[0]; // Good size if ((bitmap.getWidth()==128)&&(bitmap.getHeight()==128)) { // Make a copy for (int i=0; i<128*128; i++) { // Copy the pixel array[i].R=pPixel->R; array[i].G=pPixel->G; array[i].B=pPixel->B; array[i].A=pPixel->A; pPixel++; } } else { // Error message QString s = tr("The bitmap must have a size of 128x128 (%1)").arg(fileName); QMessageBox::information (this, tr("Import border"), s); } // 256 or 128 ? CTileBorder border; border.set (128, 128, array); tileBankBrowser.getTileSet (tileSetIndex)->setBorder ((CTile::TBitmap) tileTextureButtonGroup->checkedId(), border); // Message QMessageBox::information (this, tr("Import border"), tr("The border has been changed.")); } }
//TODO titegus: replace that by 4 buttons Export128Diffuse, Export128Additive, Export256Diffuse, Export256Diffuse ? void CTile_browser_dlg::on_exportBorderPushButton_clicked() { // Select a file QFileDialog::Options options; QString selectedFilter; QString fileName = QFileDialog::getSaveFileName(this, tr("Choose Bitmap"), QString(tileBankBrowser.getAbsPath().c_str()) , "Targa Bitmap(*.tga);;All Files (*.*);;", &selectedFilter, options); if (!fileName.isEmpty()) { fileName = QDir::toNativeSeparators(fileName); // Get the border of the bank std::vector<NLMISC::CBGRA> array; // 256 or 128 ? int width, height; //TODO titegus: And So what if Alpha ??? and what about border256 ??? tileBankBrowser.getTileSet (tileSetIndex)->getBorder128 ((CTile::TBitmap)tileTextureButtonGroup->checkedId())->get (width, height, array); // Make a bitmap if (width&&height) { NLMISC::CBitmap bitmap; bitmap.resize (width, height, NLMISC::CBitmap::RGBA); // Get pixel CRGBA *pPixel=(CRGBA*)&bitmap.getPixels()[0]; // Make a copy for (int i=0; i<width*height; i++) { // Copy the pixel pPixel->R=array[i].R; pPixel->G=array[i].G; pPixel->B=array[i].B; pPixel->A=array[i].A; pPixel++; } // Write the bitmap bool error=false; try { COFile file; if (file.open (fileName.toStdString().c_str())) { // Export bitmap.writeTGA (file, 32); } else error=true; } catch (Exception& e) { const char *toto=e.what (); error=true; } // Error during export ? if (error) { // Error message QString s = tr("Can't write bitmap %1").arg(fileName); QMessageBox::information (this, tr("Export border"), s); } } } }