Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /**
  2.  * \file macros.h
  3.  * A collection of useful macros.
  4.  */
  5.  
  6. /*
  7.  * Mesa 3-D graphics library
  8.  *
  9.  * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
  10.  *
  11.  * Permission is hereby granted, free of charge, to any person obtaining a
  12.  * copy of this software and associated documentation files (the "Software"),
  13.  * to deal in the Software without restriction, including without limitation
  14.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  15.  * and/or sell copies of the Software, and to permit persons to whom the
  16.  * Software is furnished to do so, subject to the following conditions:
  17.  *
  18.  * The above copyright notice and this permission notice shall be included
  19.  * in all copies or substantial portions of the Software.
  20.  *
  21.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  22.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  23.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  24.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  25.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  26.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  27.  * OTHER DEALINGS IN THE SOFTWARE.
  28.  */
  29.  
  30.  
  31. #ifndef MACROS_H
  32. #define MACROS_H
  33.  
  34. #include "util/macros.h"
  35. #include "util/u_math.h"
  36. #include "imports.h"
  37.  
  38.  
  39. /**
  40.  * \name Integer / float conversion for colors, normals, etc.
  41.  */
  42. /*@{*/
  43.  
  44. /** Convert GLubyte in [0,255] to GLfloat in [0.0,1.0] */
  45. extern GLfloat _mesa_ubyte_to_float_color_tab[256];
  46. #define UBYTE_TO_FLOAT(u) _mesa_ubyte_to_float_color_tab[(unsigned int)(u)]
  47.  
  48. /** Convert GLfloat in [0.0,1.0] to GLubyte in [0,255] */
  49. #define FLOAT_TO_UBYTE(X)   ((GLubyte) (GLint) ((X) * 255.0F))
  50.  
  51.  
  52. /** Convert GLbyte in [-128,127] to GLfloat in [-1.0,1.0] */
  53. #define BYTE_TO_FLOAT(B)    ((2.0F * (B) + 1.0F) * (1.0F/255.0F))
  54.  
  55. /** Convert GLfloat in [-1.0,1.0] to GLbyte in [-128,127] */
  56. #define FLOAT_TO_BYTE(X)    ( (((GLint) (255.0F * (X))) - 1) / 2 )
  57.  
  58.  
  59. /** Convert GLbyte to GLfloat while preserving zero */
  60. #define BYTE_TO_FLOATZ(B)   ((B) == 0 ? 0.0F : BYTE_TO_FLOAT(B))
  61.  
  62.  
  63. /** Convert GLbyte in [-128,127] to GLfloat in [-1.0,1.0], texture/fb data */
  64. #define BYTE_TO_FLOAT_TEX(B)    ((B) == -128 ? -1.0F : (B) * (1.0F/127.0F))
  65.  
  66. /** Convert GLfloat in [-1.0,1.0] to GLbyte in [-128,127], texture/fb data */
  67. #define FLOAT_TO_BYTE_TEX(X)    CLAMP( (GLint) (127.0F * (X)), -128, 127 )
  68.  
  69. /** Convert GLushort in [0,65535] to GLfloat in [0.0,1.0] */
  70. #define USHORT_TO_FLOAT(S)  ((GLfloat) (S) * (1.0F / 65535.0F))
  71.  
  72. /** Convert GLfloat in [0.0,1.0] to GLushort in [0, 65535] */
  73. #define FLOAT_TO_USHORT(X)   ((GLuint) ((X) * 65535.0F))
  74.  
  75.  
  76. /** Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0] */
  77. #define SHORT_TO_FLOAT(S)   ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
  78.  
  79. /** Convert GLfloat in [-1.0,1.0] to GLshort in [-32768,32767] */
  80. #define FLOAT_TO_SHORT(X)   ( (((GLint) (65535.0F * (X))) - 1) / 2 )
  81.  
  82. /** Convert GLshort to GLfloat while preserving zero */
  83. #define SHORT_TO_FLOATZ(S)   ((S) == 0 ? 0.0F : SHORT_TO_FLOAT(S))
  84.  
  85.  
  86. /** Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0], texture/fb data */
  87. #define SHORT_TO_FLOAT_TEX(S)    ((S) == -32768 ? -1.0F : (S) * (1.0F/32767.0F))
  88.  
  89. /** Convert GLfloat in [-1.0,1.0] to GLshort in [-32768,32767], texture/fb data */
  90. #define FLOAT_TO_SHORT_TEX(X)    ( (GLint) (32767.0F * (X)) )
  91.  
  92.  
  93. /** Convert GLuint in [0,4294967295] to GLfloat in [0.0,1.0] */
  94. #define UINT_TO_FLOAT(U)    ((GLfloat) ((U) * (1.0F / 4294967295.0)))
  95.  
  96. /** Convert GLfloat in [0.0,1.0] to GLuint in [0,4294967295] */
  97. #define FLOAT_TO_UINT(X)    ((GLuint) ((X) * 4294967295.0))
  98.  
  99.  
  100. /** Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0] */
  101. #define INT_TO_FLOAT(I)     ((GLfloat) ((2.0F * (I) + 1.0F) * (1.0F/4294967294.0)))
  102.  
  103. /** Convert GLfloat in [-1.0,1.0] to GLint in [-2147483648,2147483647] */
  104. /* causes overflow:
  105. #define FLOAT_TO_INT(X)     ( (((GLint) (4294967294.0 * (X))) - 1) / 2 )
  106. */
  107. /* a close approximation: */
  108. #define FLOAT_TO_INT(X)     ( (GLint) (2147483647.0 * (X)) )
  109.  
  110. /** Convert GLfloat in [-1.0,1.0] to GLint64 in [-(1<<63),(1 << 63) -1] */
  111. #define FLOAT_TO_INT64(X)     ( (GLint64) (9223372036854775807.0 * (double)(X)) )
  112.  
  113.  
  114. /** Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0], texture/fb data */
  115. #define INT_TO_FLOAT_TEX(I)    ((I) == -2147483648 ? -1.0F : (I) * (1.0F/2147483647.0))
  116.  
  117. /** Convert GLfloat in [-1.0,1.0] to GLint in [-2147483648,2147483647], texture/fb data */
  118. #define FLOAT_TO_INT_TEX(X)    ( (GLint) (2147483647.0 * (X)) )
  119.  
  120.  
  121. #define BYTE_TO_UBYTE(b)   ((GLubyte) ((b) < 0 ? 0 : (GLubyte) (b)))
  122. #define SHORT_TO_UBYTE(s)  ((GLubyte) ((s) < 0 ? 0 : (GLubyte) ((s) >> 7)))
  123. #define USHORT_TO_UBYTE(s) ((GLubyte) ((s) >> 8))
  124. #define INT_TO_UBYTE(i)    ((GLubyte) ((i) < 0 ? 0 : (GLubyte) ((i) >> 23)))
  125. #define UINT_TO_UBYTE(i)   ((GLubyte) ((i) >> 24))
  126.  
  127.  
  128. #define BYTE_TO_USHORT(b)  ((b) < 0 ? 0 : ((GLushort) (((b) * 65535) / 255)))
  129. #define UBYTE_TO_USHORT(b) (((GLushort) (b) << 8) | (GLushort) (b))
  130. #define SHORT_TO_USHORT(s) ((s) < 0 ? 0 : ((GLushort) (((s) * 65535 / 32767))))
  131. #define INT_TO_USHORT(i)   ((i) < 0 ? 0 : ((GLushort) ((i) >> 15)))
  132. #define UINT_TO_USHORT(i)  ((i) < 0 ? 0 : ((GLushort) ((i) >> 16)))
  133. #define UNCLAMPED_FLOAT_TO_USHORT(us, f)  \
  134.         us = ( (GLushort) F_TO_I( CLAMP((f), 0.0F, 1.0F) * 65535.0F) )
  135. #define CLAMPED_FLOAT_TO_USHORT(us, f)  \
  136.         us = ( (GLushort) F_TO_I( (f) * 65535.0F) )
  137.  
  138. #define UNCLAMPED_FLOAT_TO_SHORT(s, f)  \
  139.         s = ( (GLshort) F_TO_I( CLAMP((f), -1.0F, 1.0F) * 32767.0F) )
  140.  
  141. /***
  142.  *** UNCLAMPED_FLOAT_TO_UBYTE: clamp float to [0,1] and map to ubyte in [0,255]
  143.  *** CLAMPED_FLOAT_TO_UBYTE: map float known to be in [0,1] to ubyte in [0,255]
  144.  ***/
  145. #ifndef DEBUG
  146. /* This function/macro is sensitive to precision.  Test very carefully
  147.  * if you change it!
  148.  */
  149. #define UNCLAMPED_FLOAT_TO_UBYTE(UB, FLT)                               \
  150.         do {                                                            \
  151.            fi_type __tmp;                                               \
  152.            __tmp.f = (FLT);                                             \
  153.            if (__tmp.i < 0)                                             \
  154.               UB = (GLubyte) 0;                                         \
  155.            else if (__tmp.i >= IEEE_ONE)                                \
  156.               UB = (GLubyte) 255;                                       \
  157.            else {                                                       \
  158.               __tmp.f = __tmp.f * (255.0F/256.0F) + 32768.0F;           \
  159.               UB = (GLubyte) __tmp.i;                                   \
  160.            }                                                            \
  161.         } while (0)
  162. #define CLAMPED_FLOAT_TO_UBYTE(UB, FLT)                                 \
  163.         do {                                                            \
  164.            fi_type __tmp;                                               \
  165.            __tmp.f = (FLT) * (255.0F/256.0F) + 32768.0F;                \
  166.            UB = (GLubyte) __tmp.i;                                      \
  167.         } while (0)
  168. #else
  169. #define UNCLAMPED_FLOAT_TO_UBYTE(ub, f) \
  170.         ub = ((GLubyte) F_TO_I(CLAMP((f), 0.0F, 1.0F) * 255.0F))
  171. #define CLAMPED_FLOAT_TO_UBYTE(ub, f) \
  172.         ub = ((GLubyte) F_TO_I((f) * 255.0F))
  173. #endif
  174.  
  175. static fi_type UINT_AS_UNION(GLuint u)
  176. {
  177.    fi_type tmp;
  178.    tmp.u = u;
  179.    return tmp;
  180. }
  181.  
  182. static inline fi_type INT_AS_UNION(GLint i)
  183. {
  184.    fi_type tmp;
  185.    tmp.i = i;
  186.    return tmp;
  187. }
  188.  
  189. static inline fi_type FLOAT_AS_UNION(GLfloat f)
  190. {
  191.    fi_type tmp;
  192.    tmp.f = f;
  193.    return tmp;
  194. }
  195.  
  196. /**
  197.  * Convert a floating point value to an unsigned fixed point value.
  198.  *
  199.  * \param frac_bits   The number of bits used to store the fractional part.
  200.  */
  201. static inline uint32_t
  202. U_FIXED(float value, uint32_t frac_bits)
  203. {
  204.    value *= (1 << frac_bits);
  205.    return value < 0.0f ? 0 : (uint32_t) value;
  206. }
  207.  
  208. /**
  209.  * Convert a floating point value to an signed fixed point value.
  210.  *
  211.  * \param frac_bits   The number of bits used to store the fractional part.
  212.  */
  213. static inline int32_t
  214. S_FIXED(float value, uint32_t frac_bits)
  215. {
  216.    return (int32_t) (value * (1 << frac_bits));
  217. }
  218. /*@}*/
  219.  
  220.  
  221. /** Stepping a GLfloat pointer by a byte stride */
  222. #define STRIDE_F(p, i)  (p = (GLfloat *)((GLubyte *)p + i))
  223. /** Stepping a GLuint pointer by a byte stride */
  224. #define STRIDE_UI(p, i)  (p = (GLuint *)((GLubyte *)p + i))
  225. /** Stepping a GLubyte[4] pointer by a byte stride */
  226. #define STRIDE_4UB(p, i)  (p = (GLubyte (*)[4])((GLubyte *)p + i))
  227. /** Stepping a GLfloat[4] pointer by a byte stride */
  228. #define STRIDE_4F(p, i)  (p = (GLfloat (*)[4])((GLubyte *)p + i))
  229. /** Stepping a \p t pointer by a byte stride */
  230. #define STRIDE_T(p, t, i)  (p = (t)((GLubyte *)p + i))
  231.  
  232.  
  233. /**********************************************************************/
  234. /** \name 4-element vector operations */
  235. /*@{*/
  236.  
  237. /** Zero */
  238. #define ZERO_4V( DST )  (DST)[0] = (DST)[1] = (DST)[2] = (DST)[3] = 0
  239.  
  240. /** Test for equality */
  241. #define TEST_EQ_4V(a,b)  ((a)[0] == (b)[0] &&   \
  242.               (a)[1] == (b)[1] &&   \
  243.               (a)[2] == (b)[2] &&   \
  244.               (a)[3] == (b)[3])
  245.  
  246. /** Test for equality (unsigned bytes) */
  247. static inline GLboolean
  248. TEST_EQ_4UBV(const GLubyte a[4], const GLubyte b[4])
  249. {
  250. #if defined(__i386__)
  251.    return *((const GLuint *) a) == *((const GLuint *) b);
  252. #else
  253.    return TEST_EQ_4V(a, b);
  254. #endif
  255. }
  256.  
  257.  
  258. /** Copy a 4-element vector */
  259. #define COPY_4V( DST, SRC )         \
  260. do {                                \
  261.    (DST)[0] = (SRC)[0];             \
  262.    (DST)[1] = (SRC)[1];             \
  263.    (DST)[2] = (SRC)[2];             \
  264.    (DST)[3] = (SRC)[3];             \
  265. } while (0)
  266.  
  267. /** Copy a 4-element unsigned byte vector */
  268. static inline void
  269. COPY_4UBV(GLubyte dst[4], const GLubyte src[4])
  270. {
  271. #if defined(__i386__)
  272.    *((GLuint *) dst) = *((GLuint *) src);
  273. #else
  274.    /* The GLuint cast might fail if DST or SRC are not dword-aligned (RISC) */
  275.    COPY_4V(dst, src);
  276. #endif
  277. }
  278.  
  279. /** Copy \p SZ elements into a 4-element vector */
  280. #define COPY_SZ_4V(DST, SZ, SRC)  \
  281. do {                              \
  282.    switch (SZ) {                  \
  283.    case 4: (DST)[3] = (SRC)[3];   \
  284.    case 3: (DST)[2] = (SRC)[2];   \
  285.    case 2: (DST)[1] = (SRC)[1];   \
  286.    case 1: (DST)[0] = (SRC)[0];   \
  287.    }                              \
  288. } while(0)
  289.  
  290. /** Copy \p SZ elements into a homegeneous (4-element) vector, giving
  291.  * default values to the remaining */
  292. #define COPY_CLEAN_4V(DST, SZ, SRC)  \
  293. do {                                 \
  294.       ASSIGN_4V( DST, 0, 0, 0, 1 );  \
  295.       COPY_SZ_4V( DST, SZ, SRC );    \
  296. } while (0)
  297.  
  298. /** Subtraction */
  299. #define SUB_4V( DST, SRCA, SRCB )           \
  300. do {                                        \
  301.       (DST)[0] = (SRCA)[0] - (SRCB)[0];     \
  302.       (DST)[1] = (SRCA)[1] - (SRCB)[1];     \
  303.       (DST)[2] = (SRCA)[2] - (SRCB)[2];     \
  304.       (DST)[3] = (SRCA)[3] - (SRCB)[3];     \
  305. } while (0)
  306.  
  307. /** Addition */
  308. #define ADD_4V( DST, SRCA, SRCB )           \
  309. do {                                        \
  310.       (DST)[0] = (SRCA)[0] + (SRCB)[0];     \
  311.       (DST)[1] = (SRCA)[1] + (SRCB)[1];     \
  312.       (DST)[2] = (SRCA)[2] + (SRCB)[2];     \
  313.       (DST)[3] = (SRCA)[3] + (SRCB)[3];     \
  314. } while (0)
  315.  
  316. /** Element-wise multiplication */
  317. #define SCALE_4V( DST, SRCA, SRCB )         \
  318. do {                                        \
  319.       (DST)[0] = (SRCA)[0] * (SRCB)[0];     \
  320.       (DST)[1] = (SRCA)[1] * (SRCB)[1];     \
  321.       (DST)[2] = (SRCA)[2] * (SRCB)[2];     \
  322.       (DST)[3] = (SRCA)[3] * (SRCB)[3];     \
  323. } while (0)
  324.  
  325. /** In-place addition */
  326. #define ACC_4V( DST, SRC )          \
  327. do {                                \
  328.       (DST)[0] += (SRC)[0];         \
  329.       (DST)[1] += (SRC)[1];         \
  330.       (DST)[2] += (SRC)[2];         \
  331.       (DST)[3] += (SRC)[3];         \
  332. } while (0)
  333.  
  334. /** Element-wise multiplication and addition */
  335. #define ACC_SCALE_4V( DST, SRCA, SRCB )     \
  336. do {                                        \
  337.       (DST)[0] += (SRCA)[0] * (SRCB)[0];    \
  338.       (DST)[1] += (SRCA)[1] * (SRCB)[1];    \
  339.       (DST)[2] += (SRCA)[2] * (SRCB)[2];    \
  340.       (DST)[3] += (SRCA)[3] * (SRCB)[3];    \
  341. } while (0)
  342.  
  343. /** In-place scalar multiplication and addition */
  344. #define ACC_SCALE_SCALAR_4V( DST, S, SRCB ) \
  345. do {                                        \
  346.       (DST)[0] += S * (SRCB)[0];            \
  347.       (DST)[1] += S * (SRCB)[1];            \
  348.       (DST)[2] += S * (SRCB)[2];            \
  349.       (DST)[3] += S * (SRCB)[3];            \
  350. } while (0)
  351.  
  352. /** Scalar multiplication */
  353. #define SCALE_SCALAR_4V( DST, S, SRCB ) \
  354. do {                                    \
  355.       (DST)[0] = S * (SRCB)[0];         \
  356.       (DST)[1] = S * (SRCB)[1];         \
  357.       (DST)[2] = S * (SRCB)[2];         \
  358.       (DST)[3] = S * (SRCB)[3];         \
  359. } while (0)
  360.  
  361. /** In-place scalar multiplication */
  362. #define SELF_SCALE_SCALAR_4V( DST, S ) \
  363. do {                                   \
  364.       (DST)[0] *= S;                   \
  365.       (DST)[1] *= S;                   \
  366.       (DST)[2] *= S;                   \
  367.       (DST)[3] *= S;                   \
  368. } while (0)
  369.  
  370. /*@}*/
  371.  
  372.  
  373. /**********************************************************************/
  374. /** \name 3-element vector operations*/
  375. /*@{*/
  376.  
  377. /** Zero */
  378. #define ZERO_3V( DST )  (DST)[0] = (DST)[1] = (DST)[2] = 0
  379.  
  380. /** Test for equality */
  381. #define TEST_EQ_3V(a,b)  \
  382.    ((a)[0] == (b)[0] &&  \
  383.     (a)[1] == (b)[1] &&  \
  384.     (a)[2] == (b)[2])
  385.  
  386. /** Copy a 3-element vector */
  387. #define COPY_3V( DST, SRC )         \
  388. do {                                \
  389.    (DST)[0] = (SRC)[0];             \
  390.    (DST)[1] = (SRC)[1];             \
  391.    (DST)[2] = (SRC)[2];             \
  392. } while (0)
  393.  
  394. /** Copy a 3-element vector with cast */
  395. #define COPY_3V_CAST( DST, SRC, CAST )  \
  396. do {                                    \
  397.    (DST)[0] = (CAST)(SRC)[0];           \
  398.    (DST)[1] = (CAST)(SRC)[1];           \
  399.    (DST)[2] = (CAST)(SRC)[2];           \
  400. } while (0)
  401.  
  402. /** Copy a 3-element float vector */
  403. #define COPY_3FV( DST, SRC )        \
  404. do {                                \
  405.    const GLfloat *_tmp = (SRC);     \
  406.    (DST)[0] = _tmp[0];              \
  407.    (DST)[1] = _tmp[1];              \
  408.    (DST)[2] = _tmp[2];              \
  409. } while (0)
  410.  
  411. /** Subtraction */
  412. #define SUB_3V( DST, SRCA, SRCB )        \
  413. do {                                     \
  414.       (DST)[0] = (SRCA)[0] - (SRCB)[0];  \
  415.       (DST)[1] = (SRCA)[1] - (SRCB)[1];  \
  416.       (DST)[2] = (SRCA)[2] - (SRCB)[2];  \
  417. } while (0)
  418.  
  419. /** Addition */
  420. #define ADD_3V( DST, SRCA, SRCB )       \
  421. do {                                    \
  422.       (DST)[0] = (SRCA)[0] + (SRCB)[0]; \
  423.       (DST)[1] = (SRCA)[1] + (SRCB)[1]; \
  424.       (DST)[2] = (SRCA)[2] + (SRCB)[2]; \
  425. } while (0)
  426.  
  427. /** In-place scalar multiplication */
  428. #define SCALE_3V( DST, SRCA, SRCB )     \
  429. do {                                    \
  430.       (DST)[0] = (SRCA)[0] * (SRCB)[0]; \
  431.       (DST)[1] = (SRCA)[1] * (SRCB)[1]; \
  432.       (DST)[2] = (SRCA)[2] * (SRCB)[2]; \
  433. } while (0)
  434.  
  435. /** In-place element-wise multiplication */
  436. #define SELF_SCALE_3V( DST, SRC )   \
  437. do {                                \
  438.       (DST)[0] *= (SRC)[0];         \
  439.       (DST)[1] *= (SRC)[1];         \
  440.       (DST)[2] *= (SRC)[2];         \
  441. } while (0)
  442.  
  443. /** In-place addition */
  444. #define ACC_3V( DST, SRC )          \
  445. do {                                \
  446.       (DST)[0] += (SRC)[0];         \
  447.       (DST)[1] += (SRC)[1];         \
  448.       (DST)[2] += (SRC)[2];         \
  449. } while (0)
  450.  
  451. /** Element-wise multiplication and addition */
  452. #define ACC_SCALE_3V( DST, SRCA, SRCB )     \
  453. do {                                        \
  454.       (DST)[0] += (SRCA)[0] * (SRCB)[0];    \
  455.       (DST)[1] += (SRCA)[1] * (SRCB)[1];    \
  456.       (DST)[2] += (SRCA)[2] * (SRCB)[2];    \
  457. } while (0)
  458.  
  459. /** Scalar multiplication */
  460. #define SCALE_SCALAR_3V( DST, S, SRCB ) \
  461. do {                                    \
  462.       (DST)[0] = S * (SRCB)[0];         \
  463.       (DST)[1] = S * (SRCB)[1];         \
  464.       (DST)[2] = S * (SRCB)[2];         \
  465. } while (0)
  466.  
  467. /** In-place scalar multiplication and addition */
  468. #define ACC_SCALE_SCALAR_3V( DST, S, SRCB ) \
  469. do {                                        \
  470.       (DST)[0] += S * (SRCB)[0];            \
  471.       (DST)[1] += S * (SRCB)[1];            \
  472.       (DST)[2] += S * (SRCB)[2];            \
  473. } while (0)
  474.  
  475. /** In-place scalar multiplication */
  476. #define SELF_SCALE_SCALAR_3V( DST, S ) \
  477. do {                                   \
  478.       (DST)[0] *= S;                   \
  479.       (DST)[1] *= S;                   \
  480.       (DST)[2] *= S;                   \
  481. } while (0)
  482.  
  483. /** In-place scalar addition */
  484. #define ACC_SCALAR_3V( DST, S )     \
  485. do {                                \
  486.       (DST)[0] += S;                \
  487.       (DST)[1] += S;                \
  488.       (DST)[2] += S;                \
  489. } while (0)
  490.  
  491. /** Assignment */
  492. #define ASSIGN_3V( V, V0, V1, V2 )  \
  493. do {                                \
  494.     V[0] = V0;                      \
  495.     V[1] = V1;                      \
  496.     V[2] = V2;                      \
  497. } while(0)
  498.  
  499. /*@}*/
  500.  
  501.  
  502. /**********************************************************************/
  503. /** \name 2-element vector operations*/
  504. /*@{*/
  505.  
  506. /** Zero */
  507. #define ZERO_2V( DST )  (DST)[0] = (DST)[1] = 0
  508.  
  509. /** Copy a 2-element vector */
  510. #define COPY_2V( DST, SRC )         \
  511. do {                        \
  512.    (DST)[0] = (SRC)[0];             \
  513.    (DST)[1] = (SRC)[1];             \
  514. } while (0)
  515.  
  516. /** Copy a 2-element vector with cast */
  517. #define COPY_2V_CAST( DST, SRC, CAST )      \
  518. do {                        \
  519.    (DST)[0] = (CAST)(SRC)[0];           \
  520.    (DST)[1] = (CAST)(SRC)[1];           \
  521. } while (0)
  522.  
  523. /** Copy a 2-element float vector */
  524. #define COPY_2FV( DST, SRC )            \
  525. do {                        \
  526.    const GLfloat *_tmp = (SRC);         \
  527.    (DST)[0] = _tmp[0];              \
  528.    (DST)[1] = _tmp[1];              \
  529. } while (0)
  530.  
  531. /** Subtraction */
  532. #define SUB_2V( DST, SRCA, SRCB )       \
  533. do {                        \
  534.       (DST)[0] = (SRCA)[0] - (SRCB)[0];     \
  535.       (DST)[1] = (SRCA)[1] - (SRCB)[1];     \
  536. } while (0)
  537.  
  538. /** Addition */
  539. #define ADD_2V( DST, SRCA, SRCB )       \
  540. do {                        \
  541.       (DST)[0] = (SRCA)[0] + (SRCB)[0];     \
  542.       (DST)[1] = (SRCA)[1] + (SRCB)[1];     \
  543. } while (0)
  544.  
  545. /** In-place scalar multiplication */
  546. #define SCALE_2V( DST, SRCA, SRCB )     \
  547. do {                        \
  548.       (DST)[0] = (SRCA)[0] * (SRCB)[0];     \
  549.       (DST)[1] = (SRCA)[1] * (SRCB)[1];     \
  550. } while (0)
  551.  
  552. /** In-place addition */
  553. #define ACC_2V( DST, SRC )          \
  554. do {                        \
  555.       (DST)[0] += (SRC)[0];         \
  556.       (DST)[1] += (SRC)[1];         \
  557. } while (0)
  558.  
  559. /** Element-wise multiplication and addition */
  560. #define ACC_SCALE_2V( DST, SRCA, SRCB )     \
  561. do {                        \
  562.       (DST)[0] += (SRCA)[0] * (SRCB)[0];    \
  563.       (DST)[1] += (SRCA)[1] * (SRCB)[1];    \
  564. } while (0)
  565.  
  566. /** Scalar multiplication */
  567. #define SCALE_SCALAR_2V( DST, S, SRCB )     \
  568. do {                        \
  569.       (DST)[0] = S * (SRCB)[0];         \
  570.       (DST)[1] = S * (SRCB)[1];         \
  571. } while (0)
  572.  
  573. /** In-place scalar multiplication and addition */
  574. #define ACC_SCALE_SCALAR_2V( DST, S, SRCB ) \
  575. do {                        \
  576.       (DST)[0] += S * (SRCB)[0];        \
  577.       (DST)[1] += S * (SRCB)[1];        \
  578. } while (0)
  579.  
  580. /** In-place scalar multiplication */
  581. #define SELF_SCALE_SCALAR_2V( DST, S )      \
  582. do {                        \
  583.       (DST)[0] *= S;                \
  584.       (DST)[1] *= S;                \
  585. } while (0)
  586.  
  587. /** In-place scalar addition */
  588. #define ACC_SCALAR_2V( DST, S )         \
  589. do {                        \
  590.       (DST)[0] += S;                \
  591.       (DST)[1] += S;                \
  592. } while (0)
  593.  
  594. /** Assign scalers to short vectors */
  595. #define ASSIGN_2V( V, V0, V1 )  \
  596. do {                            \
  597.     V[0] = V0;                  \
  598.     V[1] = V1;                  \
  599. } while(0)
  600.  
  601. /*@}*/
  602.  
  603. /** Copy \p sz elements into a homegeneous (4-element) vector, giving
  604.  * default values to the remaining components.
  605.  * The default values are chosen based on \p type.
  606.  */
  607. static inline void
  608. COPY_CLEAN_4V_TYPE_AS_UNION(fi_type dst[4], int sz, const fi_type src[4],
  609.                             GLenum type)
  610. {
  611.    switch (type) {
  612.    case GL_FLOAT:
  613.       ASSIGN_4V(dst, FLOAT_AS_UNION(0), FLOAT_AS_UNION(0),
  614.                 FLOAT_AS_UNION(0), FLOAT_AS_UNION(1));
  615.       break;
  616.    case GL_INT:
  617.       ASSIGN_4V(dst, INT_AS_UNION(0), INT_AS_UNION(0),
  618.                 INT_AS_UNION(0), INT_AS_UNION(1));
  619.       break;
  620.    case GL_UNSIGNED_INT:
  621.       ASSIGN_4V(dst, UINT_AS_UNION(0), UINT_AS_UNION(0),
  622.                 UINT_AS_UNION(0), UINT_AS_UNION(1));
  623.       break;
  624.    default:
  625.       ASSIGN_4V(dst, FLOAT_AS_UNION(0), FLOAT_AS_UNION(0),
  626.                 FLOAT_AS_UNION(0), FLOAT_AS_UNION(1)); /* silence warnings */
  627.       assert(!"Unexpected type in COPY_CLEAN_4V_TYPE_AS_UNION macro");
  628.    }
  629.    COPY_SZ_4V(dst, sz, src);
  630. }
  631.  
  632. /** \name Linear interpolation functions */
  633. /*@{*/
  634.  
  635. static inline GLfloat
  636. LINTERP(GLfloat t, GLfloat out, GLfloat in)
  637. {
  638.    return out + t * (in - out);
  639. }
  640.  
  641. static inline void
  642. INTERP_3F(GLfloat t, GLfloat dst[3], const GLfloat out[3], const GLfloat in[3])
  643. {
  644.    dst[0] = LINTERP( t, out[0], in[0] );
  645.    dst[1] = LINTERP( t, out[1], in[1] );
  646.    dst[2] = LINTERP( t, out[2], in[2] );
  647. }
  648.  
  649. static inline void
  650. INTERP_4F(GLfloat t, GLfloat dst[4], const GLfloat out[4], const GLfloat in[4])
  651. {
  652.    dst[0] = LINTERP( t, out[0], in[0] );
  653.    dst[1] = LINTERP( t, out[1], in[1] );
  654.    dst[2] = LINTERP( t, out[2], in[2] );
  655.    dst[3] = LINTERP( t, out[3], in[3] );
  656. }
  657.  
  658. /*@}*/
  659.  
  660.  
  661.  
  662. /** Clamp X to [MIN,MAX] */
  663. #define CLAMP( X, MIN, MAX )  ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
  664.  
  665. /** Minimum of two values: */
  666. #define MIN2( A, B )   ( (A)<(B) ? (A) : (B) )
  667.  
  668. /** Maximum of two values: */
  669. #define MAX2( A, B )   ( (A)>(B) ? (A) : (B) )
  670.  
  671. /** Minimum and maximum of three values: */
  672. #define MIN3( A, B, C ) ((A) < (B) ? MIN2(A, C) : MIN2(B, C))
  673. #define MAX3( A, B, C ) ((A) > (B) ? MAX2(A, C) : MAX2(B, C))
  674.  
  675. static inline unsigned
  676. minify(unsigned value, unsigned levels)
  677. {
  678.     return MAX2(1, value >> levels);
  679. }
  680.  
  681. /**
  682.  * Return true if the given value is a power of two.
  683.  *
  684.  * Note that this considers 0 a power of two.
  685.  */
  686. static inline bool
  687. is_power_of_two(unsigned value)
  688. {
  689.    return (value & (value - 1)) == 0;
  690. }
  691.  
  692. /**
  693.  * Align a value up to an alignment value
  694.  *
  695.  * If \c value is not already aligned to the requested alignment value, it
  696.  * will be rounded up.
  697.  *
  698.  * \param value  Value to be rounded
  699.  * \param alignment  Alignment value to be used.  This must be a power of two.
  700.  *
  701.  * \sa ROUND_DOWN_TO()
  702.  */
  703. #define ALIGN(value, alignment)  (((value) + (alignment) - 1) & ~((alignment) - 1))
  704.  
  705. /**
  706.  * Align a value down to an alignment value
  707.  *
  708.  * If \c value is not already aligned to the requested alignment value, it
  709.  * will be rounded down.
  710.  *
  711.  * \param value  Value to be rounded
  712.  * \param alignment  Alignment value to be used.  This must be a power of two.
  713.  *
  714.  * \sa ALIGN()
  715.  */
  716. #define ROUND_DOWN_TO(value, alignment) ((value) & ~(alignment - 1))
  717.  
  718.  
  719. /** Cross product of two 3-element vectors */
  720. static inline void
  721. CROSS3(GLfloat n[3], const GLfloat u[3], const GLfloat v[3])
  722. {
  723.    n[0] = u[1] * v[2] - u[2] * v[1];
  724.    n[1] = u[2] * v[0] - u[0] * v[2];
  725.    n[2] = u[0] * v[1] - u[1] * v[0];
  726. }
  727.  
  728.  
  729. /** Dot product of two 2-element vectors */
  730. static inline GLfloat
  731. DOT2(const GLfloat a[2], const GLfloat b[2])
  732. {
  733.    return a[0] * b[0] + a[1] * b[1];
  734. }
  735.  
  736. static inline GLfloat
  737. DOT3(const GLfloat a[3], const GLfloat b[3])
  738. {
  739.    return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
  740. }
  741.  
  742. static inline GLfloat
  743. DOT4(const GLfloat a[4], const GLfloat b[4])
  744. {
  745.    return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
  746. }
  747.  
  748.  
  749. static inline GLfloat
  750. LEN_SQUARED_3FV(const GLfloat v[3])
  751. {
  752.    return DOT3(v, v);
  753. }
  754.  
  755. static inline GLfloat
  756. LEN_SQUARED_2FV(const GLfloat v[2])
  757. {
  758.    return DOT2(v, v);
  759. }
  760.  
  761.  
  762. static inline GLfloat
  763. LEN_3FV(const GLfloat v[3])
  764. {
  765.    return sqrtf(LEN_SQUARED_3FV(v));
  766. }
  767.  
  768. static inline GLfloat
  769. LEN_2FV(const GLfloat v[2])
  770. {
  771.    return sqrtf(LEN_SQUARED_2FV(v));
  772. }
  773.  
  774.  
  775. /* Normalize a 3-element vector to unit length. */
  776. static inline void
  777. NORMALIZE_3FV(GLfloat v[3])
  778. {
  779.    GLfloat len = (GLfloat) LEN_SQUARED_3FV(v);
  780.    if (len) {
  781.       len = 1.0f / sqrtf(len);
  782.       v[0] *= len;
  783.       v[1] *= len;
  784.       v[2] *= len;
  785.    }
  786. }
  787.  
  788.  
  789. /** Test two floats have opposite signs */
  790. static inline GLboolean
  791. DIFFERENT_SIGNS(GLfloat x, GLfloat y)
  792. {
  793. #ifdef _MSC_VER
  794. #pragma warning( push )
  795. #pragma warning( disable : 6334 ) /* sizeof operator applied to an expression with an operator may yield unexpected results */
  796. #endif
  797.    return signbit(x) != signbit(y);
  798. #ifdef _MSC_VER
  799. #pragma warning( pop )
  800. #endif
  801. }
  802.  
  803.  
  804. /** casts to silence warnings with some compilers */
  805. #define ENUM_TO_INT(E)     ((GLint)(E))
  806. #define ENUM_TO_FLOAT(E)   ((GLfloat)(GLint)(E))
  807. #define ENUM_TO_DOUBLE(E)  ((GLdouble)(GLint)(E))
  808. #define ENUM_TO_BOOLEAN(E) ((E) ? GL_TRUE : GL_FALSE)
  809.  
  810.  
  811. /* Stringify */
  812. #define STRINGIFY(x) #x
  813.  
  814. #endif
  815.