BsTexAtlasGenerator.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #pragma once
  2. #include "BsPrerequisitesUtil.h"
  3. #include "BsVector2.h"
  4. namespace BansheeEngine
  5. {
  6. /**
  7. * @brief Represents a single element used as in input to
  8. * TexAtlasGenerator. Usually represents a single texture.
  9. *
  10. * @note "input" is required to be filled in before passing it to
  11. * TexAtlasGenerator.
  12. * "output" will be filled in by TexAtlasGenerator after a call to
  13. * TexAtlasGenerator::createAtlasLayout
  14. */
  15. struct TexAtlasElementDesc
  16. {
  17. struct
  18. {
  19. UINT32 width, height;
  20. } input;
  21. struct
  22. {
  23. UINT32 x, y;
  24. INT32 page;
  25. } output;
  26. };
  27. /**
  28. * @brief A single page of the texture atlas.
  29. */
  30. struct TexAtlasPageDesc
  31. {
  32. UINT32 width, height;
  33. };
  34. class TexAtlasNode;
  35. /**
  36. * @brief Organizes a set of textures into a single larger texture (an atlas) by minimizing empty space.
  37. */
  38. class BS_UTILITY_EXPORT TexAtlasGenerator
  39. {
  40. public:
  41. /**
  42. * @brief Constructs a new texture atlas generator with the provided parameters.
  43. *
  44. * @param square (optional) Should the returned texture always be square. (width == height)
  45. * This option is only used if "fixedSize" parameter is set to false.
  46. * @param maxTexWidth (optional) Maximum width of the texture.
  47. * @param maxTexHeight (optional) Maximum height of the texture.
  48. * @param fixedSize (optional) If this field is false, algorithm will try to reduce the size of the texture
  49. * if possible. If it is true, the algorithm will always produce textures of the specified
  50. * "maxTexWidth", "maxTexHeight" size.
  51. */
  52. TexAtlasGenerator(bool square = false, UINT32 maxTexWidth = 2048, UINT32 maxTexHeight = 2048, bool fixedSize = false);
  53. /**
  54. * @brief Creates an optimal texture layout by packing texture elements in order to end up with
  55. * as little empty space as possible.
  56. *
  57. * @param elements Elements to process. They need to have their "input" structures filled in,
  58. * and this method will fill "output" when it returns.
  59. *
  60. * @note Algorithm will split elements over multiple textures if they don't fit
  61. * in a single texture (Determined by maximum texture size)
  62. *
  63. * @return One or more descriptors that determine the size of the final atlas textures. Texture elements
  64. * will reference these pages with their "output.page" parameter.
  65. */
  66. Vector<TexAtlasPageDesc> createAtlasLayout(Vector<TexAtlasElementDesc>& elements) const;
  67. private:
  68. bool mSquare;
  69. bool mFixedSize;
  70. UINT32 mMaxTexWidth;
  71. UINT32 mMaxTexHeight;
  72. /**
  73. * @brief Organize all of the provide elements and place them into minimum number of pages with the specified width and height.
  74. *
  75. * Caller must ensure "elements" array has the page indexes reset to -1 before calling, otherwise it will be assumed
  76. * those elements already have assigned pages.
  77. *
  78. * Using "startPage" parameter you may add an offset to the generated page indexes.
  79. *
  80. * @return Number of pages generated.
  81. */
  82. int generatePagesForSize(Vector<TexAtlasElementDesc>& elements, UINT32 width, UINT32 height, UINT32 startPage = 0) const;
  83. /**
  84. * @brief Finds the largest element without a page that fits within the provided node.
  85. *
  86. * @return Array index of the found page, or -1 if all textures have a page.
  87. */
  88. int addLargestTextureWithoutPageThatFits(Vector<TexAtlasElementDesc>& elements, TexAtlasNode& node) const;
  89. /**
  90. * @brief Scan all of the provided elements and find the largest one that still doesn't have a page assigned.
  91. *
  92. * @return Array index of the found page, or -1 if all textures have a page.
  93. */
  94. int findLargestTextureWithoutPage(const Vector<TexAtlasElementDesc>& elements) const;
  95. /**
  96. * @brief Sorts all the texture elements so that larget elements come first.
  97. */
  98. void sortBySize(Vector<TexAtlasElementDesc>& elements) const;
  99. };
  100. }