Home | History | Annotate | Download | only in main
      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