Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1901 serge 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