Advertisement
Guest User

Untitled

a guest
Jan 4th, 2021
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.97 KB | None | 0 0
  1. /*****************************************************************************
  2. *
  3. * Swizzler
  4. *
  5. * Purpose: To allow simple manipulations of a swizzled texture, without the
  6. * hassle or overhead of unswizzling the whole thing in order to tweak a few
  7. * points on the texture. This works with both 2D and 3D textures.
  8. *
  9. * Notes:
  10. * Most of the time when messing with a texture, you will be incrementing
  11. * by a constant value in each dimension. Those deltas can be converted
  12. * to an intermediate value via the SwizzleXXX(num) methods which can be
  13. * used to quickly increment a dimension.
  14. *
  15. * The type SWIZNUM is used to represent numbers returned by the SwizzleXXX()
  16. * methods, also known as "intermediate values" in this documentation.
  17. *
  18. * Code in comments may be uncommented in order to provide some sort of
  19. * parameter sanity. It assures that any number passed to num will only
  20. * alter the dimension specified by dim.
  21. *
  22. * Elements:
  23. *
  24. * m_u = texture map (converted) u coordinate
  25. * m_v = texture map (converted) v coordinate
  26. * m_w = texture map (converted) w coordinate
  27. *
  28. * m_MaskU = internal mask for u coordinate
  29. * m_MaskV = internal mask for v coordinate
  30. * m_MaskW = internal mask for w coordinate
  31. *
  32. * m_Width = width of the texture this instance of the class has been initialized for
  33. * m_Height = height of the texture this instance of the class has been initialized for
  34. * m_Depth = depth of the texture this instance of the class has been initialized for
  35. *
  36. * Methods:
  37. * SWIZNUM SwizzleU(DWORD num) -- converts num to an intermediate value that
  38. * can be used to modify the u coordinate
  39. * SWIZNUM SwizzleV(DWORD num) -- converts num to an intermediate value that
  40. * can be used to modify the v coordinate
  41. * SWIZNUM SwizzleW(DWORD num) -- converts num to an intermediate value that
  42. * can be used to modify the w coordinate
  43. *
  44. * DWORD UnswizzleU(SWIZNUM index) -- takes an index to the swizzled texture,
  45. * and extracts & returns the u coordinate
  46. * DWORD UnswizzleV(SWIZNUM index) -- takes an index to the swizzled texture,
  47. * and extracts & returns the v coordinate
  48. * DWORD UnswizzleW(SWIZNUM index) -- takes an index to the swizzled texture,
  49. * and extracts & returns the w coordinate
  50. *
  51. * SWIZNUM SetU(SWIZNUM num) -- sets the U coordinate to num, where num is an intermediate
  52. * value returned by Convert; returns num.
  53. * SWIZNUM SetV(SWIZNUM num) -- sets the V coordinate to num, where num is an intermediate
  54. * value returned by Convert; returns num.
  55. * SWIZNUM SetW(SWIZNUM num) -- sets the W coordinate to num, where num is an intermediate
  56. * value returned by Convert; returns num.
  57. *
  58. * SWIZNUM AddU(SWIZNUM num) -- adds num to the U coordinate, where num is an intermediate value
  59. * returned by Convert; returns the new (swizzled) U coordinate
  60. * SWIZNUM AddV(SWIZNUM num) -- adds num to the V coordinate, where num is an intermediate value
  61. * returned by Convert; returns the new (swizzled) V coordinate
  62. * SWIZNUM AddW(SWIZNUM num) -- adds num to the W coordinate, where num is an intermediate value
  63. * returned by Convert; returns the new (swizzled) W coordinate
  64. *
  65. * SWIZNUM SubU(SWIZNUM num) -- subtracts num from the U coordinate, where num is an intermediate value
  66. * returned by Convert; returns the new (swizzled) U coordinate
  67. * SWIZNUM SubV(SWIZNUM num) -- subtracts num from the V coordinate, where num is an intermediate value
  68. * returned by Convert; returns the new (swizzled) V coordinate
  69. * SWIZNUM SubW(SWIZNUM num) -- subtracts num from the W coordinate, where num is an intermediate value
  70. * returned by Convert; returns the new (swizzled) W coordinate
  71. *
  72. * SWIZNUM IncU() -- increments the U coordinate by 1, returns the new (swizzled) U coordinate.
  73. * SWIZNUM IncV() -- increments the V coordinate by 1, returns the new (swizzled) V coordinate.
  74. * SWIZNUM IncW() -- increments the W coordinate by 1, returns the new (swizzled) W coordinate.
  75. *
  76. * SWIZNUM DecU() -- decrements the U coordinate by 1, returns the new (swizzled) U coordinate.
  77. * SWIZNUM DecV() -- decrements the V coordinate by 1, returns the new (swizzled) V coordinate.
  78. * SWIZNUM DecW() -- decrements the W coordinate by 1, returns the new (swizzled) W coordinate.
  79. *
  80. * SWIZNUM Get2() -- returns the index to the swizzled volume texture, based on
  81. * the U, and V coordinates, as modified by the previous methods.
  82. *
  83. * SWIZNUM Get3() -- returns the index to the swizzled volume texture, based on
  84. * the U, V, and W coordinates, as modified by the previous methods.
  85. *
  86. * Performance:
  87. * The algorithm used in most methods of this class require only Subtraction and a binary And
  88. * operation to complete the operation. In the AddXXX methods, a negation, a subtraction, and two
  89. * binary And operations are required. For this reason, the SubXXX methods are actually faster than
  90. * AddXXX. Inc and Dec are roughly the same speed however.
  91. *
  92. ****************************************************************************/
  93. #pragma once
  94.  
  95. #ifndef DWORD
  96. typedef unsigned long DWORD;
  97. #endif
  98.  
  99. typedef DWORD SWIZNUM;
  100.  
  101. class Swizzler
  102. {
  103. public:
  104.  
  105. // Dimensions of the texture
  106. DWORD m_Width;
  107. DWORD m_Height;
  108. DWORD m_Depth;
  109.  
  110. // Internal mask for each coordinate
  111. DWORD m_MaskU;
  112. DWORD m_MaskV;
  113. DWORD m_MaskW;
  114.  
  115. // Swizzled texture coordinates
  116. DWORD m_u;
  117. DWORD m_v;
  118. DWORD m_w;
  119.  
  120. Swizzler(): m_Width(0), m_Height(0), m_Depth(0),
  121. m_MaskU(0), m_MaskV(0), m_MaskW(0),
  122. m_u(0), m_v(0), m_w(0)
  123. { }
  124.  
  125. // Initializes the swizzler
  126. Swizzler(
  127. DWORD width,
  128. DWORD height,
  129. DWORD depth
  130. )
  131. {
  132. Init(width, height, depth);
  133. }
  134.  
  135. void Init(
  136. DWORD width,
  137. DWORD height,
  138. DWORD depth
  139. )
  140. {
  141. m_Width = width;
  142. m_Height = height;
  143. m_Depth = depth;
  144. m_MaskU = 0;
  145. m_MaskV = 0;
  146. m_MaskW = 0;
  147. m_u = 0;
  148. m_v = 0;
  149. m_w = 0;
  150.  
  151. DWORD i = 1;
  152. DWORD j = 1;
  153. DWORD k;
  154.  
  155. do
  156. {
  157. k = 0;
  158. if (i < width)
  159. {
  160. m_MaskU |= j;
  161. k = (j<<=1);
  162. }
  163.  
  164. if (i < height)
  165. {
  166. m_MaskV |= j;
  167. k = (j<<=1);
  168. }
  169.  
  170. if (i < depth)
  171. {
  172. m_MaskW |= j;
  173. k = (j<<=1);
  174. }
  175.  
  176. i <<= 1;
  177. }
  178. while (k);
  179. }
  180.  
  181. // Swizzles a texture coordinate
  182. SWIZNUM SwizzleU(
  183. DWORD num
  184. )
  185. {
  186. SWIZNUM r = 0;
  187.  
  188. for (DWORD i = 1; i <= m_MaskU; i <<= 1)
  189. {
  190. if (m_MaskU & i)
  191. {
  192. r |= (num & i);
  193. }
  194. else
  195. {
  196. num <<= 1;
  197. }
  198. }
  199.  
  200. return r;
  201. }
  202.  
  203. SWIZNUM SwizzleV(
  204. DWORD num
  205. )
  206. {
  207. SWIZNUM r = 0;
  208.  
  209. for (DWORD i = 1; i <= m_MaskV; i <<= 1)
  210. {
  211. if (m_MaskV & i)
  212. {
  213. r |= (num & i);
  214. }
  215. else
  216. {
  217. num <<= 1;
  218. }
  219. }
  220.  
  221. return r;
  222. }
  223.  
  224. SWIZNUM SwizzleW(
  225. DWORD num
  226. )
  227. {
  228. SWIZNUM r = 0;
  229.  
  230. for (DWORD i = 1; i <= m_MaskW; i <<= 1)
  231. {
  232. if (m_MaskW & i)
  233. {
  234. r |= (num & i);
  235. }
  236. else
  237. {
  238. num <<= 1;
  239. }
  240. }
  241.  
  242. return r;
  243. }
  244.  
  245. SWIZNUM Swizzle(
  246. DWORD u,
  247. DWORD v,
  248. DWORD w
  249. )
  250. {
  251. return SwizzleU(u) | SwizzleV(v) | SwizzleW(w);
  252. }
  253.  
  254. // Unswizzles a texture coordinate
  255. DWORD UnswizzleU(
  256. SWIZNUM num
  257. )
  258. {
  259. DWORD r = 0;
  260.  
  261. for (DWORD i = 1, j = 1; i; i <<= 1)
  262. {
  263. if (m_MaskU & i)
  264. {
  265. r |= (num & j);
  266. j <<= 1;
  267. }
  268. else
  269. {
  270. num >>= 1;
  271. }
  272. }
  273.  
  274. return r;
  275. }
  276.  
  277. DWORD UnswizzleV(
  278. SWIZNUM num
  279. )
  280. {
  281. DWORD r = 0;
  282.  
  283. for (DWORD i = 1, j = 1; i; i <<= 1)
  284. {
  285. if (m_MaskV & i)
  286. {
  287. r |= (num & j);
  288. j <<= 1;
  289. }
  290. else
  291. {
  292. num >>= 1;
  293. }
  294. }
  295.  
  296. return r;
  297. }
  298.  
  299. DWORD UnswizzleW(
  300. SWIZNUM num
  301. )
  302. {
  303. DWORD r = 0;
  304.  
  305. for (DWORD i = 1, j = 1; i; i <<= 1)
  306. {
  307. if (m_MaskW & i)
  308. {
  309. r |= (num & j);
  310. j <<= 1;
  311. }
  312. else
  313. {
  314. num >>= 1;
  315. }
  316. }
  317.  
  318. return r;
  319. }
  320.  
  321. // Sets a texture coordinate
  322. __forceinline SWIZNUM SetU(SWIZNUM num) { return m_u = num /* & m_MaskU */; }
  323. __forceinline SWIZNUM SetV(SWIZNUM num) { return m_v = num /* & m_MaskV */; }
  324. __forceinline SWIZNUM SetW(SWIZNUM num) { return m_w = num /* & m_MaskW */; }
  325.  
  326. // Adds a value to a texture coordinate
  327. __forceinline SWIZNUM AddU(SWIZNUM num) { return m_u = ( m_u - ( (0-num) & m_MaskU ) ) & m_MaskU; }
  328. __forceinline SWIZNUM AddV(SWIZNUM num) { return m_v = ( m_v - ( (0-num) & m_MaskV ) ) & m_MaskV; }
  329. __forceinline SWIZNUM AddW(SWIZNUM num) { return m_w = ( m_w - ( (0-num) & m_MaskW ) ) & m_MaskW; }
  330.  
  331. // Subtracts a value from a texture coordinate
  332. __forceinline SWIZNUM SubU(SWIZNUM num) { return m_u = ( m_u - num /* & m_MaskU */ ) & m_MaskU; }
  333. __forceinline SWIZNUM SubV(SWIZNUM num) { return m_v = ( m_v - num /* & m_MaskV */ ) & m_MaskV; }
  334. __forceinline SWIZNUM SubW(SWIZNUM num) { return m_w = ( m_w - num /* & m_MaskW */ ) & m_MaskW; }
  335.  
  336. // Increments a texture coordinate
  337. __forceinline SWIZNUM IncU() { return m_u = ( m_u - m_MaskU ) & m_MaskU; }
  338. __forceinline SWIZNUM IncV() { return m_v = ( m_v - m_MaskV ) & m_MaskV; }
  339. __forceinline SWIZNUM IncW() { return m_w = ( m_w - m_MaskW ) & m_MaskW; }
  340.  
  341. // Decrements a texture coordinate
  342. __forceinline SWIZNUM DecU() { return m_u = ( m_u - 1 ) & m_MaskU; }
  343. __forceinline SWIZNUM DecV() { return m_v = ( m_v - 1 ) & m_MaskV; }
  344. __forceinline SWIZNUM DecW() { return m_w = ( m_w - 1 ) & m_MaskW; }
  345.  
  346. // Gets the current swizzled address for a 2D or 3D texture
  347. __forceinline SWIZNUM Get2D() { return m_u | m_v; }
  348. __forceinline SWIZNUM Get3D() { return m_u | m_v | m_w; }
  349. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement