BsPixelData.h 15 KB

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