BsPixelData.h 12 KB

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