BsPixelData.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. #pragma once
  2. #include "BsCorePrerequisites.h"
  3. #include "BsPixelVolume.h"
  4. #include "BsGpuResourceData.h"
  5. #include "BsIReflectable.h"
  6. namespace BansheeEngine
  7. {
  8. /**
  9. * @brief The pixel format usable by images, textures and render surfaces.
  10. */
  11. enum PixelFormat
  12. {
  13. // Unknown pixel format.
  14. PF_UNKNOWN = 0,
  15. // 8-bit pixel format, all bits red.
  16. PF_R8 = 1,
  17. // 2 byte pixel format, 1 byte red, 1 byte green.
  18. PF_R8G8 = 2,
  19. // 24-bit pixel format, 8 bits for red, green and blue.
  20. PF_R8G8B8 = 3,
  21. // 24-bit pixel format, 8 bits for blue, green and red.
  22. PF_B8G8R8 = 4,
  23. // 32-bit pixel format, 8 bits for alpha, red, green and blue.
  24. PF_A8R8G8B8 = 5,
  25. // 32-bit pixel format, 8 bits for blue, green, red and alpha.
  26. PF_A8B8G8R8 = 6,
  27. // 32-bit pixel format, 8 bits for blue, green, red and alpha.
  28. PF_B8G8R8A8 = 7,
  29. // 32-bit pixel format, 8 bits for red, green, blue and alpha.
  30. PF_R8G8B8A8 = 8,
  31. // 32-bit pixel format, 8 bits for red, 8 bits for green, 8 bits for blue.
  32. // Like PF_A8R8G8B8, but alpha will get discarded
  33. PF_X8R8G8B8 = 9,
  34. // 32-bit pixel format, 8 bits for blue, 8 bits for green, 8 bits for red.
  35. // Like PF_A8B8G8R8, but alpha will get discarded.
  36. PF_X8B8G8R8 = 10,
  37. // 32-bit pixel format, 8 bits for red, 8 bits for green, 8 bits for blue.
  38. // Like PF_R8G8B8A8, but alpha will get discarded.
  39. PF_R8G8B8X8 = 11,
  40. // 32-bit pixel format, 8 bits for blue, 8 bits for green, 8 bits for red.
  41. // Like PF_B8G8R8A8, but alpha will get discarded.
  42. PF_B8G8R8X8 = 12,
  43. // 24-bit pixel format, 8 bits for red, green and blue.
  44. PF_BYTE_RGB = PF_R8G8B8,
  45. // 24-bit pixel format, 8 bits for blue, green and red.
  46. PF_BYTE_BGR = PF_B8G8R8,
  47. // 32-bit pixel format, 8 bits for blue, green, red and alpha.
  48. PF_BYTE_BGRA = PF_B8G8R8A8,
  49. // 32-bit pixel format, 8 bits for red, green, blue and alpha.
  50. PF_BYTE_RGBA = PF_R8G8B8A8,
  51. // DXT1/BC1 format containing opaque RGB or 1-bit alpha RGB. 4 bits per pixel.
  52. PF_BC1 = 13,
  53. // DXT3/BC2 format containing RGB with premultiplied alpha. 4 bits per pixel.
  54. PF_BC1a = 14,
  55. // DXT3/BC2 format containing RGB with explicit alpha. 8 bits per pixel.
  56. PF_BC2 = 15,
  57. // DXT5/BC2 format containing RGB with explicit alpha. 8 bits per pixel. Better alpha gradients than BC2.
  58. PF_BC3 = 16,
  59. // One channel compressed format. 4 bits per pixel.
  60. PF_BC4 = 17,
  61. // Two channel compressed format. 8 bits per pixel.
  62. PF_BC5 = 18,
  63. // Format storing RGB in half (16-bit) floating point format usable for HDR. 8 bits per pixel.
  64. PF_BC6H = 19,
  65. // Format storing RGB with optional alpha channel. Similar to BC1/BC2/BC3 formats but with higher quality and higher decompress overhead. 8 bits per pixel.
  66. PF_BC7 = 20,
  67. // 16-bit pixel format, 16 bits (float) for red
  68. PF_FLOAT16_R = 21,
  69. // 32-bit, 2-channel s10e5 floating point pixel format, 16-bit red, 16-bit green
  70. PF_FLOAT16_RG = 22,
  71. // 48-bit pixel format, 16 bits (float) for red, 16 bits (float) for green, 16 bits (float) for blue
  72. PF_FLOAT16_RGB = 23,
  73. // 64-bit pixel format, 16 bits (float) for red, 16 bits (float) for green, 16 bits (float) for blue, 16 bits (float) for alpha
  74. PF_FLOAT16_RGBA = 24,
  75. // 32-bit pixel format, 32 bits (float) for red
  76. PF_FLOAT32_R = 25,
  77. // 64-bit, 2-channel floating point pixel format, 32-bit red, 32-bit green
  78. PF_FLOAT32_RG = 26,
  79. // 96-bit pixel format, 32 bits (float) for red, 32 bits (float) for green, 32 bits (float) for blue
  80. PF_FLOAT32_RGB = 27,
  81. // 128-bit pixel format, 32 bits (float) for red, 32 bits (float) for green, 32 bits (float) for blue, 32 bits (float) for alpha
  82. PF_FLOAT32_RGBA = 28,
  83. // Depth stencil format, 32bit depth, 8bit stencil + 24 unused
  84. PF_D32_S8X24 = 29,
  85. // Depth stencil fomrat, 24bit depth + 8bit stencil
  86. PF_D24S8 = 30,
  87. // Depth format, 32bits
  88. PF_D32 = 31,
  89. // Depth format, 16bits
  90. PF_D16 = 32,
  91. // 32-bit float format, 11 bits (float) for red, 11 bits (float) for green, 10 bits (float) for blue. Framebuffer only format, not for CPU use.
  92. PF_FLOAT_R11G11B10 = 33,
  93. // 32-bit unsigned normalized format, 10 bits (float) for red, 10 bits (float) for green, 10 bits (float) for blue, and two bits for alpha. Framebuffer only format, not for CPU use.
  94. PF_UNORM_R10G10B10A2 = 34,
  95. // Number of pixel formats currently defined
  96. PF_COUNT = 35
  97. };
  98. typedef Vector<PixelFormat> PixelFormatList;
  99. /**
  100. * @brief Flags defining some properties of pixel formats.
  101. */
  102. enum PixelFormatFlags {
  103. // This format has an alpha channel
  104. PFF_HASALPHA = 0x00000001,
  105. // This format is compressed. This invalidates the values in elemBytes,
  106. // elemBits and the bit counts as these might not be fixed in a compressed format.
  107. PFF_COMPRESSED = 0x00000002,
  108. // This is a floating point format
  109. PFF_FLOAT = 0x00000004,
  110. // This is a depth format (for depth textures)
  111. PFF_DEPTH = 0x00000008,
  112. // Format is in native endian. Generally true for the 16, 24 and 32 bits
  113. // formats which can be represented as machine integers.
  114. PFF_NATIVEENDIAN = 0x00000010
  115. };
  116. /**
  117. * @brief Types of pixel components
  118. */
  119. enum PixelComponentType
  120. {
  121. PCT_BYTE = 0, /**< Byte per component */
  122. PCT_SHORT = 1, /**< Short per component */
  123. PCT_FLOAT16 = 2, /**< 16 bit float per component */
  124. PCT_FLOAT32 = 3, /**< 32 bit float per component */
  125. PCT_PACKED_R11G11B10 = 4, /**< 11 bits for first two components, 10 for third component. */
  126. PCT_PACKED_R10G10B10A2 = 5, /**< 10 bits for first three components, 2 bits for last component */
  127. PCT_COUNT = 4 /**< Number of pixel types */
  128. };
  129. /**
  130. * @brief A buffer describing a volume (3D), image (2D) or line (1D) of pixels in memory.
  131. * Pixels are stored as a succession of "depth" slices, each containing "height" rows of
  132. * "width" pixels.
  133. *
  134. * As any GpuResourceData this is used primarily for reading and writing from/to a GPU resource,
  135. * and is normally constructed by the resource itself. However you may still construct it manually
  136. * and use it for other purposes if needed.
  137. *
  138. * @note You must call allocateInternalBuffer or set the buffer in some other way before reading/writing
  139. * from this object.
  140. *
  141. * @see GpuResourceData
  142. */
  143. class BS_CORE_EXPORT PixelData : public GpuResourceData
  144. {
  145. public:
  146. PixelData() {}
  147. ~PixelData() {}
  148. /**
  149. * @brief Constructs a new object with an internal buffer capable of holding "extents" volume of pixels,
  150. * where each pixel is of the specified pixel format. Extent offsets are also stored, but are not used
  151. * internally.
  152. */
  153. PixelData(const PixelVolume &extents, PixelFormat pixelFormat)
  154. :mExtents(extents), mFormat(pixelFormat)
  155. {
  156. setConsecutive();
  157. }
  158. /**
  159. * @brief Constructs a new object with an internal buffer capable of holding volume of pixels described by
  160. * provided width, height and depth, where each pixel is of the specified pixel format.
  161. */
  162. PixelData(UINT32 width, UINT32 height, UINT32 depth, PixelFormat pixelFormat)
  163. : mExtents(0, 0, 0, width, height, depth), mFormat(pixelFormat)
  164. {
  165. setConsecutive();
  166. }
  167. PixelData(const PixelData& copy);
  168. PixelData& operator=(const PixelData& rhs);
  169. /**
  170. * @brief Returns the number of pixels that offsets one row from another. This can be
  171. * "width", but doesn't have to be as some buffers require padding.
  172. */
  173. UINT32 getRowPitch() const { return mRowPitch; }
  174. /**
  175. * @brief Returns the number of pixels that offsets one depth slice from another. This can be
  176. * "width * height", but doesn't have to be as some buffers require padding.
  177. */
  178. UINT32 getSlicePitch() const { return mSlicePitch; }
  179. /**
  180. * @brief Sets the pitch (in pixels) that determines offset between rows of the pixel buffer.
  181. * Call this before allocating the buffer.
  182. */
  183. void setRowPitch(UINT32 rowPitch) { mRowPitch = rowPitch; }
  184. /**
  185. * @brief Sets the pitch (in pixels) that determines offset between depth slices of the pixel buffer.
  186. * Call this before allocating the buffer.
  187. */
  188. void setSlicePitch(UINT32 slicePitch) { mSlicePitch = slicePitch; }
  189. /**
  190. * @brief Returns the number of extra pixels in a row (non-zero only if rows are not
  191. * consecutive (row pitch is larger than width)).
  192. */
  193. UINT32 getRowSkip() const { return mRowPitch - getWidth(); }
  194. /**
  195. * @brief Returns the number of extra pixels in a depth slice (non-zero only if
  196. * slices aren't consecutive (slice pitch is larger than width*height).
  197. */
  198. UINT32 getSliceSkip() const { return mSlicePitch - (getHeight() * mRowPitch); }
  199. /**
  200. * @brief Returns the pixel format used by the internal buffer for storing the pixels.
  201. */
  202. PixelFormat getFormat() const { return mFormat; }
  203. /**
  204. * @brief Returns width of the buffer in pixels.
  205. */
  206. UINT32 getWidth() const { return mExtents.getWidth(); }
  207. /**
  208. * @brief Returns height of the buffer in pixels.
  209. */
  210. UINT32 getHeight() const { return mExtents.getHeight(); }
  211. /**
  212. * @brief Returns depth of the buffer in pixels.
  213. */
  214. UINT32 getDepth() const { return mExtents.getDepth(); }
  215. /**
  216. * @brief Returns left-most start of the pixel volume. This value is not used internally in any way.
  217. * It is just passed through from the constructor.
  218. */
  219. UINT32 getLeft() const { return mExtents.left; }
  220. /**
  221. * @brief Returns right-most end of the pixel volume. This value is not used internally in any way.
  222. * It is just passed through from the constructor.
  223. */
  224. UINT32 getRight() const { return mExtents.right; }
  225. /**
  226. * @brief Returns top-most start of the pixel volume. This value is not used internally in any way.
  227. * It is just passed through from the constructor.
  228. */
  229. UINT32 getTop() const { return mExtents.top; }
  230. /**
  231. * @brief Returns bottom-most end of the pixel volume. This value is not used internally in any way.
  232. * It is just passed through from the constructor.
  233. */
  234. UINT32 getBottom() const { return mExtents.bottom; }
  235. /**
  236. * @brief Returns front-most start of the pixel volume. This value is not used internally in any way.
  237. * It is just passed through from the constructor.
  238. */
  239. UINT32 getFront() const { return mExtents.front; }
  240. /**
  241. * @brief Returns back-most end of the pixel volume. This value is not used internally in any way.
  242. * It is just passed through from the constructor.
  243. */
  244. UINT32 getBack() const { return mExtents.back; }
  245. /**
  246. * @brief Returns extents of the pixel volume this object is capable of holding.
  247. */
  248. PixelVolume getExtents() const { return mExtents; }
  249. /**
  250. * @brief Return whether this buffer is laid out consecutive in memory
  251. * (i.e. the pitches are equal to the dimensions).
  252. */
  253. bool isConsecutive() const
  254. {
  255. return mRowPitch == getWidth() && mSlicePitch == getWidth()*getHeight();
  256. }
  257. /**
  258. * @brief Return the size (in bytes) this image would take if it was
  259. * laid out consecutive in memory.
  260. */
  261. UINT32 getConsecutiveSize() const;
  262. /**
  263. * @brief Return the size (in bytes) of the buffer this image requires.
  264. */
  265. UINT32 getSize() const;
  266. /**
  267. * @brief Returns pixel data containing a sub-volume of this object. Returned
  268. * data will not have its own buffer, but will instead point to this one.
  269. * It is up to the caller to ensure this object outlives any sub-volume objects.
  270. */
  271. PixelData getSubVolume(const PixelVolume &def) const;
  272. /**
  273. * @brief Returns pixel color at the specified coordinates.
  274. */
  275. Color getColorAt(UINT32 x, UINT32 y, UINT32 z = 0);
  276. /**
  277. * @brief Sets the pixel color at the specified coordinates.
  278. */
  279. void setColorAt(Color const &cv, UINT32 x, UINT32 y, UINT32 z = 0);
  280. /**
  281. * @brief Converts all the internal data into an array of colors.
  282. * Array is mapped as such: arrayIdx = x + y * width + z * width * height.
  283. */
  284. Vector<Color> getColors() const;
  285. /**
  286. * @brief Initializes the internal buffer with the provided set of colors.
  287. * The array should be of width * height * depth size and mapped
  288. * as such: arrayIdx = x + y * width + z * width * height.
  289. */
  290. void setColors(const Vector<Color>& colors);
  291. /**
  292. * @brief Initializes the internal buffer with the provided set of colors.
  293. * The array should be of width * height * depth size and mapped
  294. * as such: arrayIdx = x + y * width + z * width * height.
  295. */
  296. void setColors(Color* colors, UINT32 numElements);
  297. /**
  298. * @brief Constructs a new object with an internal buffer capable of holding "extents" volume of pixels,
  299. * where each pixel is of the specified pixel format. Extent offsets are also stored, but are not used
  300. * internally.
  301. */
  302. static PixelDataPtr create(const PixelVolume &extents, PixelFormat pixelFormat);
  303. /**
  304. * @brief Constructs a new object with an internal buffer capable of holding volume of pixels described by
  305. * provided width, height and depth, where each pixel is of the specified pixel format.
  306. */
  307. static PixelDataPtr create(UINT32 width, UINT32 height, UINT32 depth, PixelFormat pixelFormat);
  308. private:
  309. /**
  310. * @brief Set the rowPitch and slicePitch so that the buffer is laid out consecutive
  311. * in memory. Does not actually modify the buffer itself.
  312. */
  313. void setConsecutive()
  314. {
  315. mRowPitch = getWidth();
  316. mSlicePitch = getWidth()*getHeight();
  317. }
  318. /**
  319. * @brief Initializes the internal buffer with the provided set of colors.
  320. * The array should be of width * height * depth size and mapped
  321. * as such: arrayIdx = x + y * width + z * width * height.
  322. *
  323. * @note A generic method that is reused in other more specific "setColors" calls.
  324. */
  325. template<class T>
  326. void setColorsInternal(const T& colors, UINT32 numElements);
  327. /**
  328. * @brief Returns the needed size of the internal buffer, in bytes.
  329. */
  330. UINT32 getInternalBufferSize() const;
  331. private:
  332. PixelVolume mExtents;
  333. PixelFormat mFormat;
  334. UINT32 mRowPitch;
  335. UINT32 mSlicePitch;
  336. /************************************************************************/
  337. /* SERIALIZATION */
  338. /************************************************************************/
  339. public:
  340. friend class PixelDataRTTI;
  341. static RTTITypeBase* getRTTIStatic();
  342. virtual RTTITypeBase* getRTTI() const;
  343. };
  344. }