ManaPlus
Public Member Functions | Static Public Member Functions | Static Private Member Functions
AtlasManager Class Reference

#include <atlasmanager.h>

Public Member Functions

 AtlasManager ()
 

Static Public Member Functions

static AtlasResourceloadTextureAtlas (const std::string &name, const StringVect &files)
 
static AtlasResourceloadEmptyAtlas (const std::string &name, const StringVect &files)
 
static void injectToResources (const AtlasResource *const resource)
 
static void moveToDeleted (AtlasResource *const resource)
 

Static Private Member Functions

static void loadImages (const StringVect &files, std::vector< Image * > &images)
 
static void loadEmptyImages (const StringVect &files, std::vector< Image * > &images)
 
static void emptySort (const std::string &name, std::vector< TextureAtlas * > &atlases, const std::vector< Image * > &images)
 
static void simpleSort (const std::string &name, std::vector< TextureAtlas * > &atlases, const std::vector< Image * > &images, int size)
 
static void createSDLAtlas (TextureAtlas *const atlas)
 
static void convertAtlas (TextureAtlas *const atlas)
 
static void convertEmptyAtlas (TextureAtlas *const atlas)
 

Detailed Description

Definition at line 36 of file atlasmanager.h.

Constructor & Destructor Documentation

◆ AtlasManager()

AtlasManager::AtlasManager ( )

Definition at line 57 of file atlasmanager.cpp.

58 {
59 }

Member Function Documentation

◆ convertAtlas()

void AtlasManager::convertAtlas ( TextureAtlas *const  atlas)
staticprivate

Definition at line 450 of file atlasmanager.cpp.

451 {
452  // no check for null pointer in atlas because it was in caller
453  // convert surface to OpemGL image
454  Image *const oldImage = atlas->atlasImage;
455 
456  if (oldImage->mSDLSurface != nullptr)
457  {
459  atlas->atlasImage->mSDLSurface);
460  oldImage->decRef();
461  }
462 
463  Image *const image = atlas->atlasImage;
464  if (image == nullptr)
465  return;
466 
467  image->mIdPath = atlas->name;
468 #ifdef DEBUG_IMAGES
469  logger->log("set name %p, %s", static_cast<void*>(image),
470  image->mIdPath.c_str());
471 #endif // DEBUG_IMAGES
472 
473  image->incRef();
474 
475  FOR_EACH (STD_VECTOR<AtlasItem*>::iterator, it, atlas->items)
476  {
477  AtlasItem *const item = *it;
478  // delete SDL Image
479  delete item->image;
480  // store OpenGL image
481  item->image = image->getSubImage(item->x, item->y,
482  item->width, item->height);
483  Image *const image2 = item->image;
484  if (image2 != nullptr)
485  {
486  image2->mIdPath = item->name;
487 #ifdef DEBUG_IMAGES
488  logger->log("set name %p, %s", static_cast<void*>(image2),
489  image2->mIdPath.c_str());
490 #endif // DEBUG_IMAGES
491 
492  image2->incRef();
493  }
494  }
495 }
virtual Image * loadSurface(SDL_Surface *const)
Definition: imagehelper.h:73
void log(const char *const log_text,...)
Definition: logger.cpp:269
#define FOR_EACH(type, iter, array)
Definition: foreach.h:25
ImageHelper * imageHelper
Definition: imagehelper.cpp:44
Logger * logger
Definition: logger.cpp:89
int height
Definition: atlasitem.h:59
Image * image
Definition: atlasitem.h:54
int width
Definition: atlasitem.h:58
std::string name
Definition: atlasitem.h:55
std::string name
Definition: textureatlas.h:74
Image * atlasImage
Definition: textureatlas.h:75
std::vector< AtlasItem * > items
Definition: textureatlas.h:78

References TextureAtlas::atlasImage, FOR_EACH, AtlasItem::height, AtlasItem::image, imageHelper, TextureAtlas::items, ImageHelper::loadSurface(), Logger::log(), logger, AtlasItem::name, TextureAtlas::name, AtlasItem::width, AtlasItem::x, and AtlasItem::y.

Referenced by loadTextureAtlas().

◆ convertEmptyAtlas()

void AtlasManager::convertEmptyAtlas ( TextureAtlas *const  atlas)
staticprivate

Definition at line 403 of file atlasmanager.cpp.

404 {
405  // no check for null pointer in atlas because it was in caller
406  // convert surface to OpemGL image
407  Image *const oldImage = atlas->atlasImage;
408 
409  if (oldImage->mSDLSurface != nullptr)
410  {
412  atlas->atlasImage->mSDLSurface);
413  oldImage->decRef();
414  }
415 
416  Image *const image = atlas->atlasImage;
417  if (image == nullptr)
418  return;
419 
420  image->mIdPath = atlas->name;
421 #ifdef DEBUG_IMAGES
422  logger->log("set name %p, %s", static_cast<void*>(image),
423  image->mIdPath.c_str());
424 #endif // DEBUG_IMAGES
425 
426  image->incRef();
427 
428  FOR_EACH (STD_VECTOR<AtlasItem*>::iterator, it, atlas->items)
429  {
430  AtlasItem *const item = *it;
431  // delete SDL Image
432  delete item->image;
433  // store OpenGL image
434  item->image = image->getSubImage(item->x, item->y,
435  item->width, item->height);
436  Image *const image2 = item->image;
437  if (image2 != nullptr)
438  {
439  image2->mIdPath = item->name;
440 #ifdef DEBUG_IMAGES
441  logger->log("set empty name %p, %s", static_cast<void*>(image2),
442  image2->mIdPath.c_str());
443 #endif // DEBUG_IMAGES
444 
445  image2->incRef();
446  }
447  }
448 }

References TextureAtlas::atlasImage, FOR_EACH, AtlasItem::height, AtlasItem::image, imageHelper, TextureAtlas::items, ImageHelper::loadSurface(), Logger::log(), logger, AtlasItem::name, TextureAtlas::name, AtlasItem::width, AtlasItem::x, and AtlasItem::y.

Referenced by loadEmptyAtlas().

◆ createSDLAtlas()

void AtlasManager::createSDLAtlas ( TextureAtlas *const  atlas)
staticprivate

< Surface is in system memory

Definition at line 314 of file atlasmanager.cpp.

315 {
316  BLOCK_START("AtlasManager::createSDLAtlas")
317 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
318  const uint32_t rmask = 0xff000000U;
319  const uint32_t gmask = 0x00ff0000U;
320  const uint32_t bmask = 0x0000ff00U;
321  const uint32_t amask = 0x000000ffU;
322 #else // SDL_BYTEORDER == SDL_BIG_ENDIAN
323 
324  const uint32_t rmask = 0x000000ffU;
325  const uint32_t gmask = 0x0000ff00U;
326  const uint32_t bmask = 0x00ff0000U;
327  const uint32_t amask = 0xff000000U;
328 #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
329 
330  // do not create atlas based on only one image
331  if (atlas->items.size() == 1)
332  {
333  logger->log("Skip atlas creation because only one image in atlas.");
334  BLOCK_END("AtlasManager::createSDLAtlas")
335  return;
336  }
337 
338  // using only power of two sizes.
339  atlas->width = powerOfTwo(atlas->width);
340  atlas->height = powerOfTwo(atlas->height);
341 
342  const int width = atlas->width;
343  const int height = atlas->height;
344  BLOCK_START("AtlasManager::createSDLAtlas create surface")
345  // temp SDL surface for atlas
346  SDL_Surface *const surface = MSDL_CreateRGBSurface(SDL_SWSURFACE,
347  width, height, 32U, rmask, gmask, bmask, amask);
348  if (surface == nullptr)
349  {
350  reportAlways("Error creating surface for atlas. Size: %dx%d",
351  width,
352  height)
353  BLOCK_END("AtlasManager::createSDLAtlas")
354  return;
355  }
356  BLOCK_END("AtlasManager::createSDLAtlas create surface")
357 
358 #ifdef OPENGLERRORS
359  logger->log("OpenGL debug: creating atlase %dx%d", width, height);
360 #endif // OPENGLERRORS
361 
362  Image *image = imageHelper->loadSurface(surface);
363  // free SDL atlas surface
364  MSDL_FreeSurface(surface);
365  if (image == nullptr)
366  {
367  reportAlways("Error converting surface to texture. Size: %dx%d",
368  width,
369  height)
370  return;
371  }
372 
373  // drawing SDL images to surface
374  FOR_EACH (STD_VECTOR<AtlasItem*>::iterator, it, atlas->items)
375  {
376  AtlasItem *const item = *it;
377  imageHelper->copySurfaceToImage(image, item->x, item->y,
378  item->image->mSDLSurface);
379 #ifdef OPENGLERRORS
380  logger->log("OpenGL debug: put atlas image %s (size %dx%d),"
381  " into %d,%d to %d,%d",
382  item->name.c_str(),
383  item->image->mSDLSurface->w,
384  item->image->mSDLSurface->h,
385  item->x,
386  item->y,
387  item->x + item->image->mSDLSurface->w - 1,
388  item->y + item->image->mSDLSurface->h - 1);
389  if (item->x >= width)
390  logger->log("OpenGL error: start x position outside of atlas");
391  if (item->y >= height)
392  logger->log("OpenGL error: start y position outside of atlas");
393  if (item->x + item->image->mSDLSurface->w - 1 >= width)
394  logger->log("OpenGL error: end x position outside of atlas");
395  if (item->y + item->image->mSDLSurface->h - 1 >= height)
396  logger->log("OpenGL error: end y position outside of atlas");
397 #endif // OPENGLERRORS
398  }
399  atlas->atlasImage = image;
400  BLOCK_END("AtlasManager::createSDLAtlas")
401 }
#define reportAlways(...)
Definition: checkutils.h:253
static void createSDLAtlas(TextureAtlas *const atlas)
virtual void copySurfaceToImage(const Image *const image, const int x, const int y, SDL_Surface *const surface) const
Definition: imagehelper.h:86
#define MSDL_CreateRGBSurface(flags, w, h, d, r, g, b, a)
Definition: debug.h:55
#define MSDL_FreeSurface(surface)
Definition: debug.h:54
if(!vert) return
int powerOfTwo(const unsigned int input)
Definition: mathutils.h:237
#define BLOCK_END(name)
Definition: perfomance.h:80
#define BLOCK_START(name)
Definition: perfomance.h:79

References TextureAtlas::atlasImage, BLOCK_END, BLOCK_START, ImageHelper::copySurfaceToImage(), FOR_EACH, TextureAtlas::height, AtlasItem::image, imageHelper, TextureAtlas::items, ImageHelper::loadSurface(), Logger::log(), logger, MSDL_CreateRGBSurface, MSDL_FreeSurface, AtlasItem::name, powerOfTwo(), reportAlways, TextureAtlas::width, AtlasItem::x, and AtlasItem::y.

Referenced by loadTextureAtlas().

◆ emptySort()

void AtlasManager::emptySort ( const std::string &  name,
std::vector< TextureAtlas * > &  atlases,
const std::vector< Image * > &  images 
)
staticprivate

Definition at line 276 of file atlasmanager.cpp.

279 {
280  BLOCK_START("AtlasManager::simpleSort")
281  TextureAtlas *atlas = new TextureAtlas;
282  STD_VECTOR<Image*>::const_iterator it = images.begin();
283  const STD_VECTOR<Image*>::const_iterator it_end = images.end();
284  for (it = images.begin(); it != it_end; ++ it)
285  {
286  const Image *const img = *it;
287  if (img != nullptr)
288  {
289  atlas->name = std::string("atlas_").append(name).append(
290  "_").append(img->mIdPath);
291  break;
292  }
293  }
294 
295  for (it = images.begin(); it != it_end; ++ it)
296  {
297  Image *const img = *it;
298  if (img != nullptr)
299  {
300  AtlasItem *const item = new AtlasItem(img);
301  item->name = img->mIdPath;
302  item->x = 0;
303  item->y = 0;
304  atlas->items.push_back(item);
305  }
306  }
307  if (!atlas->items.empty())
308  atlases.push_back(atlas);
309  else
310  delete atlas;
311  BLOCK_END("AtlasManager::simpleSort")
312 }
#define new
Definition: debug_new.h:147
#define STD_VECTOR
Definition: vector.h:30

References BLOCK_END, BLOCK_START, TextureAtlas::items, AtlasItem::name, TextureAtlas::name, AtlasItem::x, and AtlasItem::y.

Referenced by loadEmptyAtlas().

◆ injectToResources()

void AtlasManager::injectToResources ( const AtlasResource *const  resource)
static

Definition at line 497 of file atlasmanager.cpp.

498 {
499  if (resource == nullptr)
500  return;
501  FOR_EACH (STD_VECTOR<TextureAtlas*>::const_iterator,
502  it, resource->atlases)
503  {
504  // add each atlas image to resources
505  TextureAtlas *const atlas = *it;
506  if (atlas != nullptr)
507  {
508  Image *const image = atlas->atlasImage;
509  if (image != nullptr)
510  ResourceManager::addResource(atlas->name, image);
511  FOR_EACH (STD_VECTOR<AtlasItem*>::iterator, it2, atlas->items)
512  {
513  AtlasItem *const item = *it2;
514  if (item == nullptr)
515  continue;
516  // add each atlas sub image to resources
518  }
519  }
520  }
521 }
std::vector< TextureAtlas * > atlases
Definition: atlasresource.h:52
bool addResource(const std::string &idPath, Resource *const resource)

References ResourceManager::addResource(), AtlasResource::atlases, TextureAtlas::atlasImage, FOR_EACH, AtlasItem::image, TextureAtlas::items, AtlasItem::name, and TextureAtlas::name.

Referenced by AtlasResource::incRef().

◆ loadEmptyAtlas()

AtlasResource * AtlasManager::loadEmptyAtlas ( const std::string &  name,
const StringVect files 
)
static

Definition at line 97 of file atlasmanager.cpp.

99 {
100  STD_VECTOR<TextureAtlas*> atlases;
101  STD_VECTOR<Image*> images;
102  AtlasResource *resource = new AtlasResource;
103 
104  loadEmptyImages(files, images);
105 
106  // sorting images on atlases.
107  emptySort(name, atlases, images);
108 
109  FOR_EACH (STD_VECTOR<TextureAtlas*>::iterator, it, atlases)
110  {
111  TextureAtlas *const atlas = *it;
112  if (atlas == nullptr)
113  continue;
114 
115  atlas->atlasImage = new Image(0,
116  1024, 1024,
117  1024, 1024);
118  // convert SDL images to OpenGL
119  convertEmptyAtlas(atlas);
120 
121  resource->atlases.push_back(atlas);
122  }
123 
124  BLOCK_END("AtlasManager::loadTextureAtlas")
125  return resource;
126 }
static void loadEmptyImages(const StringVect &files, std::vector< Image * > &images)
static void emptySort(const std::string &name, std::vector< TextureAtlas * > &atlases, const std::vector< Image * > &images)
static void convertEmptyAtlas(TextureAtlas *const atlas)

References AtlasResource::atlases, TextureAtlas::atlasImage, BLOCK_END, convertEmptyAtlas(), emptySort(), FOR_EACH, ParticleType::Image, and loadEmptyImages().

Referenced by EmptyAtlasLoader::load().

◆ loadEmptyImages()

void AtlasManager::loadEmptyImages ( const StringVect files,
std::vector< Image * > &  images 
)
staticprivate

Definition at line 178 of file atlasmanager.cpp.

180 {
181  BLOCK_START("AtlasManager::loadEmptyImages")
182 
183  FOR_EACH (StringVectCIter, it, files)
184  {
185  const std::string str = *it;
186  // check is image with same name already in cache
187  // and if yes, move it to deleted set
188  Resource *const res = ResourceManager::getTempResource(str);
189  if (res != nullptr)
190  {
191  // increase counter because in moveToDeleted it will be decreased.
192  res->incRef();
194  }
195 
196  Image *const image = new Image(0,
197  2048, 2048,
198  2048, 2048);
199  image->mIdPath = str;
200  images.push_back(image);
201  }
202  BLOCK_END("AtlasManager::loadEmptyImages")
203 }
virtual void incRef()
Definition: resource.cpp:38
void moveToDeleted(Resource *const res)
Resource * getTempResource(const std::string &idPath)
StringVect::const_iterator StringVectCIter
Definition: stringvector.h:31

References BLOCK_END, BLOCK_START, FOR_EACH, ResourceManager::getTempResource(), ParticleType::Image, Resource::incRef(), and ResourceManager::moveToDeleted().

Referenced by loadEmptyAtlas().

◆ loadImages()

void AtlasManager::loadImages ( const StringVect files,
std::vector< Image * > &  images 
)
staticprivate

Definition at line 128 of file atlasmanager.cpp.

130 {
131  BLOCK_START("AtlasManager::loadImages")
132 
133  FOR_EACH (StringVectCIter, it, files)
134  {
135  const std::string str = *it;
136  // check is image with same name already in cache
137  // and if yes, move it to deleted set
138  Resource *const res = ResourceManager::getTempResource(str);
139  if (res != nullptr)
140  {
141  // increase counter because in moveToDeleted it will be decreased.
142  res->incRef();
144  }
145 
146  std::string path = str;
147  const size_t p = path.find('|');
148  Dye *d = nullptr;
149  if (p != std::string::npos)
150  {
151  d = new Dye(path.substr(p + 1));
152  path = path.substr(0, p);
153  }
154 
155  SDL_RWops *const rw = VirtFs::rwopsOpenRead(path);
156  if (rw != nullptr)
157  {
158  Image *const image = d != nullptr ?
159  surfaceImageHelper->load(rw, *d)
160  : surfaceImageHelper->load(rw);
161 
162  if (image != nullptr)
163  {
164  image->mIdPath = str;
165 #ifdef DEBUG_IMAGES
166  logger->log("set name %p, %s", static_cast<void*>(image),
167  image->mIdPath.c_str());
168 #endif // DEBUG_IMAGES
169 
170  images.push_back(image);
171  }
172  }
173  delete d;
174  }
175  BLOCK_END("AtlasManager::loadImages")
176 }
Definition: dye.h:41
Image * load(SDL_RWops *const rw)
Definition: imagehelper.cpp:50
ImageHelper * surfaceImageHelper
Definition: imagehelper.cpp:45
SDL_RWops * rwopsOpenRead(const std::string &fname)
Definition: rwops.cpp:107

References BLOCK_END, BLOCK_START, FOR_EACH, ResourceManager::getTempResource(), Resource::incRef(), ImageHelper::load(), Logger::log(), logger, ResourceManager::moveToDeleted(), VirtFs::rwopsOpenRead(), and surfaceImageHelper.

Referenced by loadTextureAtlas().

◆ loadTextureAtlas()

AtlasResource * AtlasManager::loadTextureAtlas ( const std::string &  name,
const StringVect files 
)
static

Definition at line 61 of file atlasmanager.cpp.

63 {
64  BLOCK_START("AtlasManager::loadTextureAtlas")
65  STD_VECTOR<TextureAtlas*> atlases;
66  STD_VECTOR<Image*> images;
67  AtlasResource *resource = new AtlasResource;
68 
69  loadImages(files, images);
70  int maxSize = OpenGLImageHelper::getTextureSize();
71 #if !defined(ANDROID) && !defined(__APPLE__)
72  int sz = settings.textureSize;
73  if (maxSize > sz)
74  maxSize = sz;
75 #endif // !defined(ANDROID) && !defined(__APPLE__)
76 
77  // sorting images on atlases.
78  simpleSort(name, atlases, images, maxSize);
79 
80  FOR_EACH (STD_VECTOR<TextureAtlas*>::iterator, it, atlases)
81  {
82  TextureAtlas *const atlas = *it;
83  if (atlas == nullptr)
84  continue;
85 
86  createSDLAtlas(atlas);
87  if (atlas->atlasImage == nullptr)
88  continue;
89  convertAtlas(atlas);
90  resource->atlases.push_back(atlas);
91  }
92 
93  BLOCK_END("AtlasManager::loadTextureAtlas")
94  return resource;
95 }
static void loadImages(const StringVect &files, std::vector< Image * > &images)
static void convertAtlas(TextureAtlas *const atlas)
static void simpleSort(const std::string &name, std::vector< TextureAtlas * > &atlases, const std::vector< Image * > &images, int size)
unsigned int textureSize
Definition: settings.h:132
Settings settings
Definition: settings.cpp:32

References AtlasResource::atlases, TextureAtlas::atlasImage, BLOCK_END, BLOCK_START, convertAtlas(), createSDLAtlas(), FOR_EACH, OpenGLImageHelper::getTextureSize(), loadImages(), settings, simpleSort(), and Settings::textureSize.

Referenced by AtlasLoader::load().

◆ moveToDeleted()

void AtlasManager::moveToDeleted ( AtlasResource *const  resource)
static

Definition at line 523 of file atlasmanager.cpp.

524 {
525  if (resource == nullptr)
526  return;
527  FOR_EACH (STD_VECTOR<TextureAtlas*>::iterator, it, resource->atlases)
528  {
529  // move each atlas image to deleted
530  TextureAtlas *const atlas = *it;
531  if (atlas != nullptr)
532  {
533  Image *const image = atlas->atlasImage;
534  if (image != nullptr)
535  {
536  // move each atlas image to deleted
538  }
539  FOR_EACH (STD_VECTOR<AtlasItem*>::iterator, it2, atlas->items)
540  {
541  AtlasItem *const item = *it2;
542  if (item != nullptr)
543  {
544  Image *const image2 = item->image;
545  if (image2 != nullptr)
546  {
547  // move each atlas sub image to deleted
549  }
550  }
551  }
552  }
553  }
554 }

References AtlasResource::atlases, TextureAtlas::atlasImage, FOR_EACH, AtlasItem::image, TextureAtlas::items, and ResourceManager::moveToDeleted().

Referenced by AtlasResource::decRef().

◆ simpleSort()

void AtlasManager::simpleSort ( const std::string &  name,
std::vector< TextureAtlas * > &  atlases,
const std::vector< Image * > &  images,
int  size 
)
staticprivate

Definition at line 205 of file atlasmanager.cpp.

209 {
210  BLOCK_START("AtlasManager::simpleSort")
211  int x = 0;
212  int y = 0;
213  int tempHeight = 0;
214  TextureAtlas *atlas = new TextureAtlas;
215  STD_VECTOR<Image*>::const_iterator it = images.begin();
216  const STD_VECTOR<Image*>::const_iterator it_end = images.end();
217  for (it = images.begin(); it != it_end; ++ it)
218  {
219  const Image *const img = *it;
220  if (img != nullptr)
221  {
222  atlas->name = std::string("atlas_").append(name).append(
223  "_").append(img->mIdPath);
224  break;
225  }
226  }
227 
228  for (it = images.begin(); it != it_end; ++ it)
229  {
230  Image *const img = *it;
231  if (img != nullptr)
232  {
233  AtlasItem *const item = new AtlasItem(img);
234  item->name = img->mIdPath;
235  // start next line
236  if (x + img->mBounds.w > size)
237  {
238  x = 0;
239  y += tempHeight;
240  tempHeight = 0;
241  }
242 
243  // can't put image with this height
244  if (y + img->mBounds.h > size)
245  {
246  x = 0;
247  y = 0;
248  atlases.push_back(atlas);
249  atlas = new TextureAtlas;
250  atlas->name = std::string("atlas_").append(name).append(
251  "_").append(img->mIdPath);
252  }
253 
254  if (img->mBounds.h > tempHeight)
255  tempHeight = img->mBounds.h;
256 
257  item->x = x;
258  item->y = y;
259  atlas->items.push_back(item);
260 
261  // continue put textures in line
262  x += img->mBounds.w;
263  if (x > atlas->width)
264  atlas->width = x;
265  if (y + img->mBounds.h > atlas->height)
266  atlas->height = y + img->mBounds.h;
267  }
268  }
269  if (!atlas->items.empty())
270  atlases.push_back(atlas);
271  else
272  delete atlas;
273  BLOCK_END("AtlasManager::simpleSort")
274 }
int size()
Definition: emotedb.cpp:306

References BLOCK_END, BLOCK_START, TextureAtlas::height, TextureAtlas::items, AtlasItem::name, TextureAtlas::name, EmoteDB::size(), TextureAtlas::width, x, AtlasItem::x, y, and AtlasItem::y.

Referenced by loadTextureAtlas().


The documentation for this class was generated from the following files: