• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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