macros.h revision c1f859d4
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] */
43extern 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 GLushort in [0,65536] to GLfloat in [0.0,1.0] */
58#define USHORT_TO_FLOAT(S)  ((GLfloat) (S) * (1.0F / 65535.0F))
59
60/** Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0] */
61#define SHORT_TO_FLOAT(S)   ((2.0F * (S) + 1.0F) * (1.0F/65535.0F))
62
63/** Convert GLfloat in [0.0,1.0] to GLshort in [-32768,32767] */
64#define FLOAT_TO_SHORT(X)   ( (((GLint) (65535.0F * (X))) - 1) / 2 )
65
66
67/** Convert GLuint in [0,4294967295] to GLfloat in [0.0,1.0] */
68#define UINT_TO_FLOAT(U)    ((GLfloat) (U) * (1.0F / 4294967295.0F))
69
70/** Convert GLfloat in [0.0,1.0] to GLuint in [0,4294967295] */
71#define FLOAT_TO_UINT(X)    ((GLuint) ((X) * 4294967295.0))
72
73
74/** Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0] */
75#define INT_TO_FLOAT(I)     ((2.0F * (I) + 1.0F) * (1.0F/4294967294.0F))
76
77/** Convert GLfloat in [-1.0,1.0] to GLint in [-2147483648,2147483647] */
78/* causes overflow:
79#define FLOAT_TO_INT(X)     ( (((GLint) (4294967294.0F * (X))) - 1) / 2 )
80*/
81/* a close approximation: */
82#define FLOAT_TO_INT(X)     ( (GLint) (2147483647.0 * (X)) )
83
84
85#define BYTE_TO_UBYTE(b)   ((GLubyte) ((b) < 0 ? 0 : (GLubyte) (b)))
86#define SHORT_TO_UBYTE(s)  ((GLubyte) ((s) < 0 ? 0 : (GLubyte) ((s) >> 7)))
87#define USHORT_TO_UBYTE(s) ((GLubyte) ((s) >> 8))
88#define INT_TO_UBYTE(i)    ((GLubyte) ((i) < 0 ? 0 : (GLubyte) ((i) >> 23)))
89#define UINT_TO_UBYTE(i)   ((GLubyte) ((i) >> 24))
90
91
92#define BYTE_TO_USHORT(b)  ((b) < 0 ? 0 : ((GLushort) (((b) * 65535) / 255)))
93#define UBYTE_TO_USHORT(b) (((GLushort) (b) << 8) | (GLushort) (b))
94#define SHORT_TO_USHORT(s) ((s) < 0 ? 0 : ((GLushort) (((s) * 65535 / 32767))))
95#define INT_TO_USHORT(i)   ((i) < 0 ? 0 : ((GLushort) ((i) >> 15)))
96#define UINT_TO_USHORT(i)  ((i) < 0 ? 0 : ((GLushort) ((i) >> 16)))
97#define UNCLAMPED_FLOAT_TO_USHORT(us, f)  \
98        us = ( (GLushort) IROUND( CLAMP((f), 0.0, 1.0) * 65535.0F) )
99#define CLAMPED_FLOAT_TO_USHORT(us, f)  \
100        us = ( (GLushort) IROUND( (f) * 65535.0F) )
101
102/*@}*/
103
104
105/** Stepping a GLfloat pointer by a byte stride */
106#define STRIDE_F(p, i)  (p = (GLfloat *)((GLubyte *)p + i))
107/** Stepping a GLuint pointer by a byte stride */
108#define STRIDE_UI(p, i)  (p = (GLuint *)((GLubyte *)p + i))
109/** Stepping a GLubyte[4] pointer by a byte stride */
110#define STRIDE_4UB(p, i)  (p = (GLubyte (*)[4])((GLubyte *)p + i))
111/** Stepping a GLfloat[4] pointer by a byte stride */
112#define STRIDE_4F(p, i)  (p = (GLfloat (*)[4])((GLubyte *)p + i))
113/** Stepping a GLchan[4] pointer by a byte stride */
114#define STRIDE_4CHAN(p, i)  (p = (GLchan (*)[4])((GLubyte *)p + i))
115/** Stepping a GLchan pointer by a byte stride */
116#define STRIDE_CHAN(p, i)  (p = (GLchan *)((GLubyte *)p + i))
117/** Stepping a \p t pointer by a byte stride */
118#define STRIDE_T(p, t, i)  (p = (t)((GLubyte *)p + i))
119
120
121/**********************************************************************/
122/** \name 4-element vector operations */
123/*@{*/
124
125/** Zero */
126#define ZERO_4V( DST )  (DST)[0] = (DST)[1] = (DST)[2] = (DST)[3] = 0
127
128/** Test for equality */
129#define TEST_EQ_4V(a,b)  ((a)[0] == (b)[0] &&   \
130              (a)[1] == (b)[1] &&   \
131              (a)[2] == (b)[2] &&   \
132              (a)[3] == (b)[3])
133
134/** Test for equality (unsigned bytes) */
135#if defined(__i386__)
136#define TEST_EQ_4UBV(DST, SRC) *((GLuint*)(DST)) == *((GLuint*)(SRC))
137#else
138#define TEST_EQ_4UBV(DST, SRC) TEST_EQ_4V(DST, SRC)
139#endif
140
141/** Copy a 4-element vector */
142#define COPY_4V( DST, SRC )         \
143do {                                \
144   (DST)[0] = (SRC)[0];             \
145   (DST)[1] = (SRC)[1];             \
146   (DST)[2] = (SRC)[2];             \
147   (DST)[3] = (SRC)[3];             \
148} while (0)
149
150/** Copy a 4-element vector with cast */
151#define COPY_4V_CAST( DST, SRC, CAST )  \
152do {                                    \
153   (DST)[0] = (CAST)(SRC)[0];           \
154   (DST)[1] = (CAST)(SRC)[1];           \
155   (DST)[2] = (CAST)(SRC)[2];           \
156   (DST)[3] = (CAST)(SRC)[3];           \
157} while (0)
158
159/** Copy a 4-element unsigned byte vector */
160#if defined(__i386__)
161#define COPY_4UBV(DST, SRC)                 \
162do {                                        \
163   *((GLuint*)(DST)) = *((GLuint*)(SRC));   \
164} while (0)
165#else
166/* The GLuint cast might fail if DST or SRC are not dword-aligned (RISC) */
167#define COPY_4UBV(DST, SRC)         \
168do {                                \
169   (DST)[0] = (SRC)[0];             \
170   (DST)[1] = (SRC)[1];             \
171   (DST)[2] = (SRC)[2];             \
172   (DST)[3] = (SRC)[3];             \
173} while (0)
174#endif
175
176/**
177 * Copy a 4-element float vector (avoid using FPU registers)
178 * XXX Could use two 64-bit moves on 64-bit systems
179 */
180#define COPY_4FV( DST, SRC )                  \
181do {                                          \
182   const GLuint *_s = (const GLuint *) (SRC); \
183   GLuint *_d = (GLuint *) (DST);             \
184   _d[0] = _s[0];                             \
185   _d[1] = _s[1];                             \
186   _d[2] = _s[2];                             \
187   _d[3] = _s[3];                             \
188} while (0)
189
190/** Copy \p SZ elements into a 4-element vector */
191#define COPY_SZ_4V(DST, SZ, SRC)  \
192do {                              \
193   switch (SZ) {                  \
194   case 4: (DST)[3] = (SRC)[3];   \
195   case 3: (DST)[2] = (SRC)[2];   \
196   case 2: (DST)[1] = (SRC)[1];   \
197   case 1: (DST)[0] = (SRC)[0];   \
198   }                              \
199} while(0)
200
201/** Copy \p SZ elements into a homegeneous (4-element) vector, giving
202 * default values to the remaining */
203#define COPY_CLEAN_4V(DST, SZ, SRC)  \
204do {                                 \
205      ASSIGN_4V( DST, 0, 0, 0, 1 );  \
206      COPY_SZ_4V( DST, SZ, SRC );    \
207} while (0)
208
209/** Subtraction */
210#define SUB_4V( DST, SRCA, SRCB )           \
211do {                                        \
212      (DST)[0] = (SRCA)[0] - (SRCB)[0];     \
213      (DST)[1] = (SRCA)[1] - (SRCB)[1];     \
214      (DST)[2] = (SRCA)[2] - (SRCB)[2];     \
215      (DST)[3] = (SRCA)[3] - (SRCB)[3];     \
216} while (0)
217
218/** Addition */
219#define ADD_4V( DST, SRCA, SRCB )           \
220do {                                        \
221      (DST)[0] = (SRCA)[0] + (SRCB)[0];     \
222      (DST)[1] = (SRCA)[1] + (SRCB)[1];     \
223      (DST)[2] = (SRCA)[2] + (SRCB)[2];     \
224      (DST)[3] = (SRCA)[3] + (SRCB)[3];     \
225} while (0)
226
227/** Element-wise multiplication */
228#define SCALE_4V( DST, SRCA, SRCB )         \
229do {                                        \
230      (DST)[0] = (SRCA)[0] * (SRCB)[0];     \
231      (DST)[1] = (SRCA)[1] * (SRCB)[1];     \
232      (DST)[2] = (SRCA)[2] * (SRCB)[2];     \
233      (DST)[3] = (SRCA)[3] * (SRCB)[3];     \
234} while (0)
235
236/** In-place addition */
237#define ACC_4V( DST, SRC )          \
238do {                                \
239      (DST)[0] += (SRC)[0];         \
240      (DST)[1] += (SRC)[1];         \
241      (DST)[2] += (SRC)[2];         \
242      (DST)[3] += (SRC)[3];         \
243} while (0)
244
245/** Element-wise multiplication and addition */
246#define ACC_SCALE_4V( DST, SRCA, SRCB )     \
247do {                                        \
248      (DST)[0] += (SRCA)[0] * (SRCB)[0];    \
249      (DST)[1] += (SRCA)[1] * (SRCB)[1];    \
250      (DST)[2] += (SRCA)[2] * (SRCB)[2];    \
251      (DST)[3] += (SRCA)[3] * (SRCB)[3];    \
252} while (0)
253
254/** In-place scalar multiplication and addition */
255#define ACC_SCALE_SCALAR_4V( DST, S, SRCB ) \
256do {                                        \
257      (DST)[0] += S * (SRCB)[0];            \
258      (DST)[1] += S * (SRCB)[1];            \
259      (DST)[2] += S * (SRCB)[2];            \
260      (DST)[3] += S * (SRCB)[3];            \
261} while (0)
262
263/** Scalar multiplication */
264#define SCALE_SCALAR_4V( DST, S, SRCB ) \
265do {                                    \
266      (DST)[0] = S * (SRCB)[0];         \
267      (DST)[1] = S * (SRCB)[1];         \
268      (DST)[2] = S * (SRCB)[2];         \
269      (DST)[3] = S * (SRCB)[3];         \
270} while (0)
271
272/** In-place scalar multiplication */
273#define SELF_SCALE_SCALAR_4V( DST, S ) \
274do {                                   \
275      (DST)[0] *= S;                   \
276      (DST)[1] *= S;                   \
277      (DST)[2] *= S;                   \
278      (DST)[3] *= S;                   \
279} while (0)
280
281/** Assignment */
282#define ASSIGN_4V( V, V0, V1, V2, V3 )  \
283do {                                    \
284    V[0] = V0;                          \
285    V[1] = V1;                          \
286    V[2] = V2;                          \
287    V[3] = V3;                          \
288} while(0)
289
290/*@}*/
291
292
293/**********************************************************************/
294/** \name 3-element vector operations*/
295/*@{*/
296
297/** Zero */
298#define ZERO_3V( DST )  (DST)[0] = (DST)[1] = (DST)[2] = 0
299
300/** Test for equality */
301#define TEST_EQ_3V(a,b)  \
302   ((a)[0] == (b)[0] &&  \
303    (a)[1] == (b)[1] &&  \
304    (a)[2] == (b)[2])
305
306/** Copy a 3-element vector */
307#define COPY_3V( DST, SRC )         \
308do {                                \
309   (DST)[0] = (SRC)[0];             \
310   (DST)[1] = (SRC)[1];             \
311   (DST)[2] = (SRC)[2];             \
312} while (0)
313
314/** Copy a 3-element vector with cast */
315#define COPY_3V_CAST( DST, SRC, CAST )  \
316do {                                    \
317   (DST)[0] = (CAST)(SRC)[0];           \
318   (DST)[1] = (CAST)(SRC)[1];           \
319   (DST)[2] = (CAST)(SRC)[2];           \
320} while (0)
321
322/** Copy a 3-element float vector */
323#define COPY_3FV( DST, SRC )        \
324do {                                \
325   const GLfloat *_tmp = (SRC);     \
326   (DST)[0] = _tmp[0];              \
327   (DST)[1] = _tmp[1];              \
328   (DST)[2] = _tmp[2];              \
329} while (0)
330
331/** Subtraction */
332#define SUB_3V( DST, SRCA, SRCB )        \
333do {                                     \
334      (DST)[0] = (SRCA)[0] - (SRCB)[0];  \
335      (DST)[1] = (SRCA)[1] - (SRCB)[1];  \
336      (DST)[2] = (SRCA)[2] - (SRCB)[2];  \
337} while (0)
338
339/** Addition */
340#define ADD_3V( DST, SRCA, SRCB )       \
341do {                                    \
342      (DST)[0] = (SRCA)[0] + (SRCB)[0]; \
343      (DST)[1] = (SRCA)[1] + (SRCB)[1]; \
344      (DST)[2] = (SRCA)[2] + (SRCB)[2]; \
345} while (0)
346
347/** In-place scalar multiplication */
348#define SCALE_3V( DST, SRCA, SRCB )     \
349do {                                    \
350      (DST)[0] = (SRCA)[0] * (SRCB)[0]; \
351      (DST)[1] = (SRCA)[1] * (SRCB)[1]; \
352      (DST)[2] = (SRCA)[2] * (SRCB)[2]; \
353} while (0)
354
355/** In-place element-wise multiplication */
356#define SELF_SCALE_3V( DST, SRC )   \
357do {                                \
358      (DST)[0] *= (SRC)[0];         \
359      (DST)[1] *= (SRC)[1];         \
360      (DST)[2] *= (SRC)[2];         \
361} while (0)
362
363/** In-place addition */
364#define ACC_3V( DST, SRC )          \
365do {                                \
366      (DST)[0] += (SRC)[0];         \
367      (DST)[1] += (SRC)[1];         \
368      (DST)[2] += (SRC)[2];         \
369} while (0)
370
371/** Element-wise multiplication and addition */
372#define ACC_SCALE_3V( DST, SRCA, SRCB )     \
373do {                                        \
374      (DST)[0] += (SRCA)[0] * (SRCB)[0];    \
375      (DST)[1] += (SRCA)[1] * (SRCB)[1];    \
376      (DST)[2] += (SRCA)[2] * (SRCB)[2];    \
377} while (0)
378
379/** Scalar multiplication */
380#define SCALE_SCALAR_3V( DST, S, SRCB ) \
381do {                                    \
382      (DST)[0] = S * (SRCB)[0];         \
383      (DST)[1] = S * (SRCB)[1];         \
384      (DST)[2] = S * (SRCB)[2];         \
385} while (0)
386
387/** In-place scalar multiplication and addition */
388#define ACC_SCALE_SCALAR_3V( DST, S, SRCB ) \
389do {                                        \
390      (DST)[0] += S * (SRCB)[0];            \
391      (DST)[1] += S * (SRCB)[1];            \
392      (DST)[2] += S * (SRCB)[2];            \
393} while (0)
394
395/** In-place scalar multiplication */
396#define SELF_SCALE_SCALAR_3V( DST, S ) \
397do {                                   \
398      (DST)[0] *= S;                   \
399      (DST)[1] *= S;                   \
400      (DST)[2] *= S;                   \
401} while (0)
402
403/** In-place scalar addition */
404#define ACC_SCALAR_3V( DST, S )     \
405do {                                \
406      (DST)[0] += S;                \
407      (DST)[1] += S;                \
408      (DST)[2] += S;                \
409} while (0)
410
411/** Assignment */
412#define ASSIGN_3V( V, V0, V1, V2 )  \
413do {                                \
414    V[0] = V0;                      \
415    V[1] = V1;                      \
416    V[2] = V2;                      \
417} while(0)
418
419/*@}*/
420
421
422/**********************************************************************/
423/** \name 2-element vector operations*/
424/*@{*/
425
426/** Zero */
427#define ZERO_2V( DST )  (DST)[0] = (DST)[1] = 0
428
429/** Copy a 2-element vector */
430#define COPY_2V( DST, SRC )         \
431do {                        \
432   (DST)[0] = (SRC)[0];             \
433   (DST)[1] = (SRC)[1];             \
434} while (0)
435
436/** Copy a 2-element vector with cast */
437#define COPY_2V_CAST( DST, SRC, CAST )      \
438do {                        \
439   (DST)[0] = (CAST)(SRC)[0];           \
440   (DST)[1] = (CAST)(SRC)[1];           \
441} while (0)
442
443/** Copy a 2-element float vector */
444#define COPY_2FV( DST, SRC )            \
445do {                        \
446   const GLfloat *_tmp = (SRC);         \
447   (DST)[0] = _tmp[0];              \
448   (DST)[1] = _tmp[1];              \
449} while (0)
450
451/** Subtraction */
452#define SUB_2V( DST, SRCA, SRCB )       \
453do {                        \
454      (DST)[0] = (SRCA)[0] - (SRCB)[0];     \
455      (DST)[1] = (SRCA)[1] - (SRCB)[1];     \
456} while (0)
457
458/** Addition */
459#define ADD_2V( DST, SRCA, SRCB )       \
460do {                        \
461      (DST)[0] = (SRCA)[0] + (SRCB)[0];     \
462      (DST)[1] = (SRCA)[1] + (SRCB)[1];     \
463} while (0)
464
465/** In-place scalar multiplication */
466#define SCALE_2V( DST, SRCA, SRCB )     \
467do {                        \
468      (DST)[0] = (SRCA)[0] * (SRCB)[0];     \
469      (DST)[1] = (SRCA)[1] * (SRCB)[1];     \
470} while (0)
471
472/** In-place addition */
473#define ACC_2V( DST, SRC )          \
474do {                        \
475      (DST)[0] += (SRC)[0];         \
476      (DST)[1] += (SRC)[1];         \
477} while (0)
478
479/** Element-wise multiplication and addition */
480#define ACC_SCALE_2V( DST, SRCA, SRCB )     \
481do {                        \
482      (DST)[0] += (SRCA)[0] * (SRCB)[0];    \
483      (DST)[1] += (SRCA)[1] * (SRCB)[1];    \
484} while (0)
485
486/** Scalar multiplication */
487#define SCALE_SCALAR_2V( DST, S, SRCB )     \
488do {                        \
489      (DST)[0] = S * (SRCB)[0];         \
490      (DST)[1] = S * (SRCB)[1];         \
491} while (0)
492
493/** In-place scalar multiplication and addition */
494#define ACC_SCALE_SCALAR_2V( DST, S, SRCB ) \
495do {                        \
496      (DST)[0] += S * (SRCB)[0];        \
497      (DST)[1] += S * (SRCB)[1];        \
498} while (0)
499
500/** In-place scalar multiplication */
501#define SELF_SCALE_SCALAR_2V( DST, S )      \
502do {                        \
503      (DST)[0] *= S;                \
504      (DST)[1] *= S;                \
505} while (0)
506
507/** In-place scalar addition */
508#define ACC_SCALAR_2V( DST, S )         \
509do {                        \
510      (DST)[0] += S;                \
511      (DST)[1] += S;                \
512} while (0)
513
514/** Assign scalers to short vectors */
515#define ASSIGN_2V( V, V0, V1 )	\
516do {				\
517    V[0] = V0;			\
518    V[1] = V1;			\
519} while(0)
520
521/*@}*/
522
523
524/** \name Linear interpolation macros */
525/*@{*/
526
527/**
528 * Linear interpolation
529 *
530 * \note \p OUT argument is evaluated twice!
531 * \note Be wary of using *coord++ as an argument to any of these macros!
532 */
533#define LINTERP(T, OUT, IN) ((OUT) + (T) * ((IN) - (OUT)))
534
535/* Can do better with integer math
536 */
537#define INTERP_UB( t, dstub, outub, inub )  \
538do {                        \
539   GLfloat inf = UBYTE_TO_FLOAT( inub );    \
540   GLfloat outf = UBYTE_TO_FLOAT( outub );  \
541   GLfloat dstf = LINTERP( t, outf, inf );  \
542   UNCLAMPED_FLOAT_TO_UBYTE( dstub, dstf ); \
543} while (0)
544
545#define INTERP_CHAN( t, dstc, outc, inc )   \
546do {                        \
547   GLfloat inf = CHAN_TO_FLOAT( inc );      \
548   GLfloat outf = CHAN_TO_FLOAT( outc );    \
549   GLfloat dstf = LINTERP( t, outf, inf );  \
550   UNCLAMPED_FLOAT_TO_CHAN( dstc, dstf );   \
551} while (0)
552
553#define INTERP_UI( t, dstui, outui, inui )  \
554   dstui = (GLuint) (GLint) LINTERP( (t), (GLfloat) (outui), (GLfloat) (inui) )
555
556#define INTERP_F( t, dstf, outf, inf )      \
557   dstf = LINTERP( t, outf, inf )
558
559#define INTERP_4F( t, dst, out, in )        \
560do {                        \
561   dst[0] = LINTERP( (t), (out)[0], (in)[0] );  \
562   dst[1] = LINTERP( (t), (out)[1], (in)[1] );  \
563   dst[2] = LINTERP( (t), (out)[2], (in)[2] );  \
564   dst[3] = LINTERP( (t), (out)[3], (in)[3] );  \
565} while (0)
566
567#define INTERP_3F( t, dst, out, in )        \
568do {                        \
569   dst[0] = LINTERP( (t), (out)[0], (in)[0] );  \
570   dst[1] = LINTERP( (t), (out)[1], (in)[1] );  \
571   dst[2] = LINTERP( (t), (out)[2], (in)[2] );  \
572} while (0)
573
574#define INTERP_4CHAN( t, dst, out, in )         \
575do {                            \
576   INTERP_CHAN( (t), (dst)[0], (out)[0], (in)[0] ); \
577   INTERP_CHAN( (t), (dst)[1], (out)[1], (in)[1] ); \
578   INTERP_CHAN( (t), (dst)[2], (out)[2], (in)[2] ); \
579   INTERP_CHAN( (t), (dst)[3], (out)[3], (in)[3] ); \
580} while (0)
581
582#define INTERP_3CHAN( t, dst, out, in )         \
583do {                            \
584   INTERP_CHAN( (t), (dst)[0], (out)[0], (in)[0] ); \
585   INTERP_CHAN( (t), (dst)[1], (out)[1], (in)[1] ); \
586   INTERP_CHAN( (t), (dst)[2], (out)[2], (in)[2] ); \
587} while (0)
588
589#define INTERP_SZ( t, vec, to, out, in, sz )                \
590do {                                    \
591   switch (sz) {                            \
592   case 4: vec[to][3] = LINTERP( (t), (vec)[out][3], (vec)[in][3] );    \
593   case 3: vec[to][2] = LINTERP( (t), (vec)[out][2], (vec)[in][2] );    \
594   case 2: vec[to][1] = LINTERP( (t), (vec)[out][1], (vec)[in][1] );    \
595   case 1: vec[to][0] = LINTERP( (t), (vec)[out][0], (vec)[in][0] );    \
596   }                                    \
597} while(0)
598
599/*@}*/
600
601
602
603/** Clamp X to [MIN,MAX] */
604#define CLAMP( X, MIN, MAX )  ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
605
606/** Assign X to CLAMP(X, MIN, MAX) */
607#define CLAMP_SELF(x, mn, mx)  \
608   ( (x)<(mn) ? ((x) = (mn)) : ((x)>(mx) ? ((x)=(mx)) : (x)) )
609
610
611
612/** Minimum of two values: */
613#define MIN2( A, B )   ( (A)<(B) ? (A) : (B) )
614
615/** Maximum of two values: */
616#define MAX2( A, B )   ( (A)>(B) ? (A) : (B) )
617
618/** Dot product of two 2-element vectors */
619#define DOT2( a, b )  ( (a)[0]*(b)[0] + (a)[1]*(b)[1] )
620
621/** Dot product of two 3-element vectors */
622#define DOT3( a, b )  ( (a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] )
623
624/** Dot product of two 4-element vectors */
625#define DOT4( a, b )  ( (a)[0]*(b)[0] + (a)[1]*(b)[1] + \
626            (a)[2]*(b)[2] + (a)[3]*(b)[3] )
627
628/** Dot product of two 4-element vectors */
629#define DOT4V(v,a,b,c,d) (v[0]*(a) + v[1]*(b) + v[2]*(c) + v[3]*(d))
630
631
632/** Cross product of two 3-element vectors */
633#define CROSS3(n, u, v)             \
634do {                        \
635   (n)[0] = (u)[1]*(v)[2] - (u)[2]*(v)[1];  \
636   (n)[1] = (u)[2]*(v)[0] - (u)[0]*(v)[2];  \
637   (n)[2] = (u)[0]*(v)[1] - (u)[1]*(v)[0];  \
638} while (0)
639
640
641/* Normalize a 3-element vector to unit length. */
642#define NORMALIZE_3FV( V )          \
643do {                        \
644   GLfloat len = (GLfloat) LEN_SQUARED_3FV(V);  \
645   if (len) {                   \
646      len = INV_SQRTF(len);         \
647      (V)[0] = (GLfloat) ((V)[0] * len);    \
648      (V)[1] = (GLfloat) ((V)[1] * len);    \
649      (V)[2] = (GLfloat) ((V)[2] * len);    \
650   }                        \
651} while(0)
652
653#define LEN_3FV( V ) (SQRTF((V)[0]*(V)[0]+(V)[1]*(V)[1]+(V)[2]*(V)[2]))
654#define LEN_2FV( V ) (SQRTF((V)[0]*(V)[0]+(V)[1]*(V)[1]))
655
656#define LEN_SQUARED_3FV( V ) ((V)[0]*(V)[0]+(V)[1]*(V)[1]+(V)[2]*(V)[2])
657#define LEN_SQUARED_2FV( V ) ((V)[0]*(V)[0]+(V)[1]*(V)[1])
658
659
660/** casts to silence warnings with some compilers */
661#define ENUM_TO_INT(E)     ((GLint)(E))
662#define ENUM_TO_FLOAT(E)   ((GLfloat)(GLint)(E))
663#define ENUM_TO_DOUBLE(E)  ((GLdouble)(GLint)(E))
664#define ENUM_TO_BOOLEAN(E) ((E) ? GL_TRUE : GL_FALSE)
665
666
667#endif
668