BsPixelUtil.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. #pragma once
  2. #include "BsCorePrerequisites.h"
  3. #include "BsPixelData.h"
  4. namespace BansheeEngine
  5. {
  6. /**
  7. * @brief Types of texture compression quality.
  8. */
  9. enum class CompressionQuality
  10. {
  11. Fastest,
  12. Normal,
  13. Production,
  14. Highest
  15. };
  16. /**
  17. * @brief Mode of the alpha channel in a texture.
  18. */
  19. enum class AlphaMode
  20. {
  21. None, /*< Texture has no alpha values. */
  22. Transparency, /*< Alpha is in the separate transparency channel. */
  23. Premultiplied /*< Alpha values have been pre-multiplied with the color values. */
  24. };
  25. /**
  26. * @brief Wrap mode to use when generating mip maps.
  27. */
  28. enum class MipMapWrapMode
  29. {
  30. Mirror,
  31. Repeat,
  32. Clamp
  33. };
  34. /**
  35. * @brief Filter to use when generating mip maps.
  36. */
  37. enum class MipMapFilter
  38. {
  39. Box,
  40. Triangle,
  41. Kaiser
  42. };
  43. /**
  44. * @brief Options used to control texture compression.
  45. */
  46. struct CompressionOptions
  47. {
  48. PixelFormat format = PF_BC1; /*< Format to compress to. Must be a format containing compressed data. */
  49. AlphaMode alphaMode = AlphaMode::None; /*< Controls how to (and if) to compress the alpha channel. */
  50. bool isNormalMap = false; /*< Determines does the input data represent a normal map. */
  51. bool isSRGB = false; /*< Determines has the input data been gamma corrected. */
  52. CompressionQuality quality = CompressionQuality::Normal; /*< Compressed image quality. Better compression might take longer to execute but will generate better results. */
  53. };
  54. /**
  55. * @brief Options used to control texture mip map generation.
  56. */
  57. struct MipMapGenOptions
  58. {
  59. MipMapFilter filter = MipMapFilter::Box; /*< Filter to use when downsamping input data. */
  60. MipMapWrapMode wrapMode = MipMapWrapMode::Mirror; /*< Determines how to downsample pixels on borders. */
  61. bool isNormalMap = false; /*< Determines does the input data represent a normal map. */
  62. bool normalizeMipmaps = false; /*< Should the downsampled values be re-normalized. Only relevant for mip-maps representing normal maps. */
  63. };
  64. /**
  65. * @brief Utility methods for converting and managing pixel data and formats.
  66. */
  67. class BS_CORE_EXPORT PixelUtil
  68. {
  69. public:
  70. /**
  71. * @brief Filtering types to use when scaling images.
  72. */
  73. enum Filter
  74. {
  75. FILTER_NEAREST, /*< No filtering is performed and nearest existing value is used. */
  76. FILTER_LINEAR /*< Box filter is applied, averaging nearby pixels. */
  77. };
  78. /**
  79. * @brief Returns the size of a single pixel of the provided pixel format,
  80. * in bytes.
  81. */
  82. static UINT32 getNumElemBytes(PixelFormat format);
  83. /**
  84. * @brief Returns the size of a single pixel of the provided pixel format,
  85. * in bits.
  86. */
  87. static UINT32 getNumElemBits( PixelFormat format );
  88. /**
  89. * @brief Returns the size of the memory region required to hold pixels of the provided size ana format.
  90. */
  91. static UINT32 getMemorySize(UINT32 width, UINT32 height, UINT32 depth, PixelFormat format);
  92. /**
  93. * @brief Calculates the size of a mip level of a texture with the provided size.
  94. */
  95. static void getSizeForMipLevel(UINT32 width, UINT32 height, UINT32 depth, UINT32 mipLevel,
  96. UINT32& mipWidth, UINT32& mipHeight, UINT32& mipDepth);
  97. /**
  98. * @brief Returns property flags for this pixel format.
  99. *
  100. * @see PixelFormatFlags
  101. */
  102. static UINT32 getFlags(PixelFormat format);
  103. /**
  104. * @brief Checks if the provided pixel format has an alpha channel.
  105. */
  106. static bool hasAlpha(PixelFormat format);
  107. /**
  108. * @brief Checks is the provided pixel format a floating point format.
  109. */
  110. static bool isFloatingPoint(PixelFormat format);
  111. /**
  112. * @brief Checks is the provided pixel format compressed.
  113. */
  114. static bool isCompressed(PixelFormat format);
  115. /**
  116. * @brief Checks is the provided pixel format a depth/stencil buffer format.
  117. */
  118. static bool isDepth(PixelFormat format);
  119. /**
  120. * @brief Checks is the provided format in native endian format.
  121. */
  122. static bool isNativeEndian(PixelFormat format);
  123. /**
  124. * @brief Checks are the provided dimensions valid for the specified pixel format.
  125. * Some formats (like DXT) require width/height to be multiples of four and some
  126. * formats dont allow depth larger than 1.
  127. */
  128. static bool isValidExtent(UINT32 width, UINT32 height, UINT32 depth, PixelFormat format);
  129. /**
  130. * @brief Returns the number of bits per each element in the provided pixel format.
  131. * This will return all zero for compressed and depth/stencil formats.
  132. */
  133. static void getBitDepths(PixelFormat format, int rgba[4]);
  134. /**
  135. * @brief Returns bit masks that determine in what bit range is each channel stored.
  136. *
  137. * @note e.g. if your color is stored in an UINT32 and you want to extract the red channel
  138. * you should AND the color UINT32 with the bit-mask for the red channel and then
  139. * right shift it by the red channel bit shift amount.
  140. */
  141. static void getBitMasks(PixelFormat format, UINT32 rgba[4]);
  142. /**
  143. * @brief Returns number of bits you need to shift a pixel element in order
  144. * to move it to the start of the data type.
  145. *
  146. * @note e.g. if your color is stored in an UINT32 and you want to extract the red channel
  147. * you should AND the color UINT32 with the bit-mask for the red channel and then
  148. * right shift it by the red channel bit shift amount.
  149. */
  150. static void getBitShifts(PixelFormat format, UINT8 rgba[4]);
  151. /**
  152. * @brief Returns the name of the pixel format.
  153. */
  154. static String getFormatName(PixelFormat srcformat);
  155. /**
  156. * @brief Returns true if the pixel data in the format can be directly accessed and read.
  157. * This is generally not true for compressed formats.
  158. */
  159. static bool isAccessible(PixelFormat srcformat);
  160. /**
  161. * @brief Returns the type of an individual pixel element in the provided format.
  162. */
  163. static PixelComponentType getElementType(PixelFormat format);
  164. /**
  165. * @brief Returns the number of pixel elements in the provided format.
  166. */
  167. static UINT32 getNumElements(PixelFormat format);
  168. /**
  169. * @brief Returns the maximum number of mip maps that can be generated until we reach
  170. * the minimum size possible. This does not count the base level.
  171. */
  172. static UINT32 getMaxMipmaps(UINT32 width, UINT32 height, UINT32 depth, PixelFormat format);
  173. /**
  174. * @brief Writes the color to the provided memory location.
  175. */
  176. static void packColor(const Color& color, PixelFormat format, void* dest);
  177. /**
  178. * @brief Writes the color to the provided memory location. If the destination
  179. * format is floating point, the byte values will be converted into [0.0, 1.0] range.
  180. */
  181. static void packColor(UINT8 r, UINT8 g, UINT8 b, UINT8 a, PixelFormat format, void* dest);
  182. /**
  183. * @brief Writes the color to the provided memory location. If the destination format
  184. * in non-floating point, the float values will be assumed to be in [0.0, 1.0] which
  185. * will be converted to integer range. ([0, 255] in the case of bytes)
  186. */
  187. static void packColor(float r, float g, float b, float a, const PixelFormat format, void* dest);
  188. /**
  189. * @brief Reads the color from the provided memory location and stores it
  190. * into the provided color object.
  191. */
  192. static void unpackColor(Color* color, PixelFormat format, const void* src);
  193. /**
  194. * @brief Reads the color from the provided memory location and stores it
  195. * into the provided color elements, as bytes clamped to [0, 255] range.
  196. */
  197. static void unpackColor(UINT8* r, UINT8* g, UINT8* b, UINT8* a, PixelFormat format, const void* src);
  198. /**
  199. * @brief Reads the color from the provided memory location and stores it
  200. * into the provided color elements. If the format is not natively floating
  201. * point a conversion is done in such a way that returned values range [0.0, 1.0].
  202. */
  203. static void unpackColor(float* r, float* g, float* b, float* a, PixelFormat format, const void* src);
  204. /**
  205. * @brief Converts pixels from one format to another. Provided pixel data objects
  206. * must have previously allocated buffers of adequate size and their sizes must match.
  207. */
  208. static void bulkPixelConversion(const PixelData& src, PixelData& dst);
  209. /**
  210. * @brief Compresses the provided data using the specified compression options.
  211. */
  212. static void compress(const PixelData& src, PixelData& dst, const CompressionOptions& options);
  213. /**
  214. * @brief Generates mip-maps from the provided source data using the specified compression options.
  215. * Returned list includes the base level.
  216. *
  217. * @returns A list of calculated mip-map data. First entry is the largest mip and other follow in
  218. * order from largest to smallest.
  219. */
  220. static Vector<PixelDataPtr> genMipmaps(const PixelData& src, const MipMapGenOptions& options);
  221. /**
  222. * @brief Scales pixel data in the source buffer and stores the scaled data in the destination buffer.
  223. * Provided pixel data objects must have previously allocated buffers of adequate size. You may
  224. * also provided a filtering method to use when scaling.
  225. */
  226. static void scale(const PixelData& src, PixelData& dst, Filter filter = FILTER_LINEAR);
  227. /**
  228. * @brief Applies gamma correction to the pixels in the provided buffer.
  229. *
  230. * @param buffer Pointer to the buffer containing the pixels.
  231. * @param gamma Gamma value to apply.
  232. * @param size Size of the buffer in bytes.
  233. * @param bpp Number of bits per pixel of the pixels in the buffer.
  234. */
  235. static void applyGamma(UINT8* buffer, float gamma, UINT32 size, UINT8 bpp);
  236. };
  237. }