Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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