BsTexAtlasGenerator.h 4.1 KB

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