CmTexAtlasGenerator.h 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #pragma once
  2. #include "CmPrerequisitesUtil.h"
  3. #include "CmVector2.h"
  4. namespace CamelotFramework
  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. class CM_UTILITY_EXPORT TexAtlasGenerator
  36. {
  37. public:
  38. /**
  39. * @brief Constructor.
  40. *
  41. * @param square (optional) Should the returned texture always be square. (width == height)
  42. * This option is only used if "fixedSize" parameter is set to false.
  43. * @param maxTexWidth (optional) Maximum width of the texture.
  44. * @param maxTexHeight (optional) Maximum height of the texture.
  45. * @param fixedSize (optional) If this field is false, algorithm will try to reduce the size of the texture
  46. * if possible. If it is true, the algorithm will always produce textures of the specified
  47. * "maxTexWidth", "maxTexHeight" size.
  48. */
  49. TexAtlasGenerator(bool square = false, UINT32 maxTexWidth = 2048, UINT32 maxTexHeight = 2048, bool fixedSize = false);
  50. /**
  51. * @brief Creates an optimal texture layout by packing texture elements in order to end up with
  52. * as little empty space as possible.
  53. *
  54. * @param elements Elements to process. They need to have their "input" structures filled in,
  55. * and this method will fill "output" when it returns.
  56. *
  57. * @note Algorithm will split elements over multiple textures if they don't fit
  58. * in a single texture (Determined by maximum texture size)
  59. *
  60. * @return One or more descriptors that determine the size of the final atlas textures. Texture elements
  61. * will reference these pages with their "output.page" parameter.
  62. */
  63. Vector<TexAtlasPageDesc>::type createAtlasLayout(Vector<TexAtlasElementDesc>::type& elements) const;
  64. private:
  65. bool mSquare;
  66. bool mFixedSize;
  67. UINT32 mMaxTexWidth;
  68. UINT32 mMaxTexHeight;
  69. int generatePagesForSize(Vector<TexAtlasElementDesc>::type& elements, UINT32 width, UINT32 height, UINT32 startPage = 0) const;
  70. int addLargestTextureWithoutPageThatFits(Vector<TexAtlasElementDesc>::type& elements, TexAtlasNode& node) const;
  71. int findLargestTextureWithoutPage(const Vector<TexAtlasElementDesc>::type& elements) const;
  72. void sortBySize(Vector<TexAtlasElementDesc>::type& elements) const;
  73. };
  74. }