BsPixelData.h 16 KB

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