CmPixelData.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. #pragma once
  2. #include "CmPrerequisitesUtil.h"
  3. #include "CmBox.h"
  4. #include "CmIReflectable.h"
  5. namespace CamelotFramework
  6. {
  7. /** The pixel format used for images, textures, and render surfaces */
  8. enum PixelFormat
  9. {
  10. /// Unknown pixel format.
  11. PF_UNKNOWN = 0,
  12. /// 8-bit pixel format, all bits red
  13. PF_R8 = 1,
  14. /// 2 byte pixel format, 1 byte red, 1 byte green
  15. PF_R8G8 = 2,
  16. /// 24-bit pixel format, 8 bits for red, green and blue.
  17. PF_R8G8B8 = 3,
  18. /// 24-bit pixel format, 8 bits for blue, green and red.
  19. PF_B8G8R8 = 4,
  20. /// 32-bit pixel format, 8 bits for alpha, red, green and blue.
  21. PF_A8R8G8B8 = 5,
  22. /// 32-bit pixel format, 8 bits for blue, green, red and alpha.
  23. PF_A8B8G8R8 = 6,
  24. /// 32-bit pixel format, 8 bits for blue, green, red and alpha.
  25. PF_B8G8R8A8 = 7,
  26. /// 32-bit pixel format, 8 bits for red, green, blue and alpha.
  27. PF_R8G8B8A8 = 8,
  28. /// 32-bit pixel format, 8 bits for red, 8 bits for green, 8 bits for blue
  29. /// like PF_A8R8G8B8, but alpha will get discarded
  30. PF_X8R8G8B8 = 9,
  31. /// 32-bit pixel format, 8 bits for blue, 8 bits for green, 8 bits for red
  32. /// like PF_A8B8G8R8, but alpha will get discarded
  33. PF_X8B8G8R8 = 10,
  34. /// 32-bit pixel format, 8 bits for red, 8 bits for green, 8 bits for blue
  35. /// like PF_R8G8B8A8, but alpha will get discarded
  36. PF_R8G8B8X8 = 11,
  37. /// 32-bit pixel format, 8 bits for blue, 8 bits for green, 8 bits for red
  38. /// like PF_B8G8R8A8, but alpha will get discarded
  39. PF_B8G8R8X8 = 12,
  40. /// 3 byte pixel format, 1 byte for red, 1 byte for green, 1 byte for blue
  41. PF_BYTE_RGB = PF_R8G8B8,
  42. /// 3 byte pixel format, 1 byte for blue, 1 byte for green, 1 byte for red
  43. PF_BYTE_BGR = PF_B8G8R8,
  44. /// 4 byte pixel format, 1 byte for blue, 1 byte for green, 1 byte for red and one byte for alpha
  45. PF_BYTE_BGRA = PF_B8G8R8A8,
  46. /// 4 byte pixel format, 1 byte for red, 1 byte for green, 1 byte for blue, and one byte for alpha
  47. PF_BYTE_RGBA = PF_R8G8B8A8,
  48. /// DDS (DirectDraw Surface) DXT1 format
  49. PF_DXT1 = 13,
  50. /// DDS (DirectDraw Surface) DXT2 format
  51. PF_DXT2 = 14,
  52. /// DDS (DirectDraw Surface) DXT3 format
  53. PF_DXT3 = 15,
  54. /// DDS (DirectDraw Surface) DXT4 format
  55. PF_DXT4 = 16,
  56. /// DDS (DirectDraw Surface) DXT5 format
  57. PF_DXT5 = 17,
  58. // 16-bit pixel format, 16 bits (float) for red
  59. PF_FLOAT16_R = 18,
  60. // 32-bit, 2-channel s10e5 floating point pixel format, 16-bit red, 16-bit green
  61. PF_FLOAT16_RG = 19,
  62. // 48-bit pixel format, 16 bits (float) for red, 16 bits (float) for green, 16 bits (float) for blue
  63. PF_FLOAT16_RGB = 20,
  64. // 64-bit pixel format, 16 bits (float) for red, 16 bits (float) for green, 16 bits (float) for blue, 16 bits (float) for alpha
  65. PF_FLOAT16_RGBA = 21,
  66. // 32-bit pixel format, 32 bits (float) for red
  67. PF_FLOAT32_R = 22,
  68. // 64-bit, 2-channel floating point pixel format, 32-bit red, 32-bit green
  69. PF_FLOAT32_RG = 23,
  70. // 96-bit pixel format, 32 bits (float) for red, 32 bits (float) for green, 32 bits (float) for blue
  71. PF_FLOAT32_RGB = 24,
  72. // 128-bit pixel format, 32 bits (float) for red, 32 bits (float) for green, 32 bits (float) for blue, 32 bits (float) for alpha
  73. PF_FLOAT32_RGBA = 25,
  74. // Depth stencil, 32bit depth, 8bit stencil + 24 unused
  75. PF_D32_S8X24 = 26,
  76. // Depth stencil, 24bit depth + 8bit stencil
  77. PF_D24S8 = 27,
  78. // Depth, 32bits
  79. PF_D32 = 28,
  80. // Depth, 16bits
  81. PF_D16 = 29,
  82. // Number of pixel formats currently defined
  83. PF_COUNT = 30
  84. };
  85. typedef vector<PixelFormat>::type PixelFormatList;
  86. /**
  87. * Flags defining some on/off properties of pixel formats
  88. */
  89. enum PixelFormatFlags {
  90. // This format has an alpha channel
  91. PFF_HASALPHA = 0x00000001,
  92. // This format is compressed. This invalidates the values in elemBytes,
  93. // elemBits and the bit counts as these might not be fixed in a compressed format.
  94. PFF_COMPRESSED = 0x00000002,
  95. // This is a floating point format
  96. PFF_FLOAT = 0x00000004,
  97. // This is a depth format (for depth textures)
  98. PFF_DEPTH = 0x00000008,
  99. // Format is in native endian. Generally true for the 16, 24 and 32 bits
  100. // formats which can be represented as machine integers.
  101. PFF_NATIVEENDIAN = 0x00000010
  102. };
  103. /** Pixel component format */
  104. enum PixelComponentType
  105. {
  106. PCT_BYTE = 0, /// Byte per component (8 bit fixed 0.0..1.0)
  107. PCT_SHORT = 1, /// Short per component (16 bit fixed 0.0..1.0))
  108. PCT_FLOAT16 = 2, /// 16 bit float per component
  109. PCT_FLOAT32 = 3, /// 32 bit float per component
  110. PCT_COUNT = 4 /// Number of pixel types
  111. };
  112. /** A primitive describing a volume (3D), image (2D) or line (1D) of pixels in memory.
  113. In case of a rectangle, depth must be 1.
  114. Pixels are stored as a succession of "depth" slices, each containing "height" rows of
  115. "width" pixels.
  116. */
  117. class CM_UTILITY_EXPORT PixelData: public Box, public IReflectable
  118. {
  119. public:
  120. /// Parameter constructor for setting the members manually
  121. PixelData() {}
  122. ~PixelData()
  123. {
  124. if(ownsData && data != nullptr)
  125. CM_DELETE_BYTES(data, ScratchAlloc);
  126. data = nullptr;
  127. }
  128. /** Constructor providing extents in the form of a Box object. This constructor
  129. assumes the pixel data is laid out consecutively in memory. (this
  130. means row after row, slice after slice, with no space in between)
  131. @param extents Extents of the region defined by data
  132. @param pixelFormat Format of this buffer
  133. @param pixelData Pointer to the actual data
  134. */
  135. PixelData(const Box &extents, PixelFormat pixelFormat, void *pixelData = nullptr):
  136. Box(extents), data(pixelData), format(pixelFormat), ownsData(false)
  137. {
  138. setConsecutive();
  139. }
  140. /** Constructor providing width, height and depth. This constructor
  141. assumes the pixel data is laid out consecutively in memory. (this
  142. means row after row, slice after slice, with no space in between)
  143. @param width Width of the region
  144. @param height Height of the region
  145. @param depth Depth of the region
  146. @param pixelFormat Format of this buffer
  147. @param pixelData Pointer to the actual data
  148. */
  149. PixelData(UINT32 width, UINT32 height, UINT32 depth, PixelFormat pixelFormat, void *pixelData = nullptr):
  150. Box(0, 0, 0, width, height, depth),
  151. data(pixelData), format(pixelFormat), ownsData(false)
  152. {
  153. setConsecutive();
  154. }
  155. PixelData(const PixelData& copy);
  156. /**
  157. * @brief Allocates an internal buffer for storing data.
  158. */
  159. UINT8* allocData(UINT32 size);
  160. /// The data pointer
  161. void *data;
  162. /// The pixel format
  163. PixelFormat format;
  164. /** Number of elements between the leftmost pixel of one row and the left
  165. pixel of the next. This value must always be equal to getWidth() (consecutive)
  166. for compressed formats.
  167. */
  168. UINT32 rowPitch;
  169. /** Number of elements between the top left pixel of one (depth) slice and
  170. the top left pixel of the next. This can be a negative value. Must be a multiple of
  171. rowPitch. This value must always be equal to getWidth()*getHeight() (consecutive)
  172. for compressed formats.
  173. */
  174. UINT32 slicePitch;
  175. /**
  176. * @brief If true then PixelData owns the data buffer and will release it when destroyed.
  177. */
  178. bool ownsData;
  179. /** Set the rowPitch and slicePitch so that the buffer is laid out consecutive
  180. in memory.
  181. */
  182. void setConsecutive()
  183. {
  184. rowPitch = getWidth();
  185. slicePitch = getWidth()*getHeight();
  186. }
  187. /** Get the number of elements between one past the rightmost pixel of
  188. one row and the leftmost pixel of the next row. (IE this is zero if rows
  189. are consecutive).
  190. */
  191. UINT32 getRowSkip() const { return rowPitch - getWidth(); }
  192. /** Get the number of elements between one past the right bottom pixel of
  193. one slice and the left top pixel of the next slice. (IE this is zero if slices
  194. are consecutive).
  195. */
  196. UINT32 getSliceSkip() const { return slicePitch - (getHeight() * rowPitch); }
  197. PixelFormat getFormat() const { return format; }
  198. /** Return whether this buffer is laid out consecutive in memory (ie the pitches
  199. are equal to the dimensions)
  200. */
  201. bool isConsecutive() const
  202. {
  203. return rowPitch == getWidth() && slicePitch == getWidth()*getHeight();
  204. }
  205. /** Return the size (in bytes) this image would take if it was
  206. laid out consecutive in memory
  207. */
  208. UINT32 getConsecutiveSize() const;
  209. /** Return a subvolume of this PixelBox.
  210. @param def Defines the bounds of the subregion to return
  211. @returns A pixel box describing the region and the data in it
  212. @remarks This function does not copy any data, it just returns
  213. a PixelBox object with a data pointer pointing somewhere inside
  214. the data of object.
  215. @throws Exception(ERR_INVALIDPARAMS) if def is not fully contained
  216. */
  217. PixelData getSubVolume(const Box &def) const;
  218. /**
  219. * Get colour value from a certain location in the PixelBox. The z coordinate
  220. * is only valid for cubemaps and volume textures. This uses the first (largest)
  221. * mipmap.
  222. */
  223. Color getColourAt(UINT32 x, UINT32 y, UINT32 z);
  224. /**
  225. * Set colour value at a certain location in the PixelBox. The z coordinate
  226. * is only valid for cubemaps and volume textures. This uses the first (largest)
  227. * mipmap.
  228. */
  229. void setColourAt(Color const &cv, UINT32 x, UINT32 y, UINT32 z);
  230. /************************************************************************/
  231. /* SERIALIZATION */
  232. /************************************************************************/
  233. public:
  234. friend class PixelDataRTTI;
  235. static RTTITypeBase* getRTTIStatic();
  236. virtual RTTITypeBase* getRTTI() const;
  237. };
  238. }