macros.h revision 0cb28418d06c30e431bdff515c1d36a812d5950d
1/* $Id: macros.h,v 1.25 2002/02/13 00:53:19 keithw Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version:  3.5
6 *
7 * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28/*
29 * A collection of useful macros.
30 */
31
32
33#ifndef MACROS_H
34#define MACROS_H
35
36
37#include "glheader.h"
38/* Do not reference mtypes.h from this file.
39 */
40
41
42/* Limits: */
43#define MAX_GLUSHORT	0xffff
44#define MAX_GLUINT	0xffffffff
45
46
47/* Pi */
48#ifndef M_PI
49#define M_PI (3.1415926)
50#endif
51
52
53/* Degrees to radians conversion: */
54#define DEG2RAD (M_PI/180.0)
55
56
57#ifndef NULL
58#define NULL 0
59#endif
60
61
62
63/*
64 * Bitmask helpers
65 */
66#define SET_BITS(WORD, BITS)    (WORD) |= (BITS)
67#define CLEAR_BITS(WORD, BITS)  (WORD) &= ~(BITS)
68#define TEST_BITS(WORD, BITS)   ((WORD) & (BITS))
69
70
71/* Stepping a GLfloat pointer by a byte stride
72 */
73#define STRIDE_F(p, i)  (p = (GLfloat *)((GLubyte *)p + i))
74#define STRIDE_UI(p, i)  (p = (GLuint *)((GLubyte *)p + i))
75#define STRIDE_4UB(p, i)  (p = (GLubyte (*)[4])((GLubyte *)p + i))
76#define STRIDE_4CHAN(p, i)  (p = (GLchan (*)[4])((GLubyte *)p + i))
77#define STRIDE_CHAN(p, i)  (p = (GLchan *)((GLubyte *)p + i))
78#define STRIDE_T(p, t, i)  (p = (t)((GLubyte *)p + i))
79
80
81#define ZERO_2V( DST )	(DST)[0] = (DST)[1] = 0
82#define ZERO_3V( DST )	(DST)[0] = (DST)[1] = (DST)[2] = 0
83#define ZERO_4V( DST )	(DST)[0] = (DST)[1] = (DST)[2] = (DST)[3] = 0
84
85
86#define TEST_EQ_4V(a,b)  ((a)[0] == (b)[0] && 	\
87			  (a)[1] == (b)[1] &&	\
88			  (a)[2] == (b)[2] &&	\
89			  (a)[3] == (b)[3])
90
91#define TEST_EQ_3V(a,b)  ((a)[0] == (b)[0] && 	\
92			  (a)[1] == (b)[1] &&	\
93			  (a)[2] == (b)[2])
94
95#if defined(__i386__)
96#define TEST_EQ_4UBV(DST, SRC) *((GLuint*)(DST)) == *((GLuint*)(SRC))
97#else
98#define TEST_EQ_4UBV(DST, SRC) TEST_EQ_4V(DST, SRC)
99#endif
100
101
102
103/* Copy short vectors: */
104#define COPY_2V( DST, SRC )			\
105do {						\
106   (DST)[0] = (SRC)[0];				\
107   (DST)[1] = (SRC)[1];				\
108} while (0)
109
110#define COPY_3V( DST, SRC )			\
111do {						\
112   (DST)[0] = (SRC)[0];				\
113   (DST)[1] = (SRC)[1];				\
114   (DST)[2] = (SRC)[2];				\
115} while (0)
116
117#define COPY_4V( DST, SRC )			\
118do {						\
119   (DST)[0] = (SRC)[0];				\
120   (DST)[1] = (SRC)[1];				\
121   (DST)[2] = (SRC)[2];				\
122   (DST)[3] = (SRC)[3];				\
123} while (0)
124
125#if defined(__i386__)
126#define COPY_4UBV(DST, SRC)			\
127do {						\
128   *((GLuint*)(DST)) = *((GLuint*)(SRC));	\
129} while (0)
130#else
131/* The GLuint cast might fail if DST or SRC are not dword-aligned (RISC) */
132#define COPY_4UBV(DST, SRC)			\
133do {						\
134   (DST)[0] = (SRC)[0];				\
135   (DST)[1] = (SRC)[1];				\
136   (DST)[2] = (SRC)[2];				\
137   (DST)[3] = (SRC)[3];				\
138} while (0)
139#endif
140
141#define COPY_2FV( DST, SRC )			\
142do {						\
143   const GLfloat *_tmp = (SRC);			\
144   (DST)[0] = _tmp[0];				\
145   (DST)[1] = _tmp[1];				\
146} while (0)
147
148#define COPY_3FV( DST, SRC )			\
149do {						\
150   const GLfloat *_tmp = (SRC);			\
151   (DST)[0] = _tmp[0];				\
152   (DST)[1] = _tmp[1];				\
153   (DST)[2] = _tmp[2];				\
154} while (0)
155
156#define COPY_4FV( DST, SRC )			\
157do {						\
158   const GLfloat *_tmp = (SRC);			\
159   (DST)[0] = _tmp[0];				\
160   (DST)[1] = _tmp[1];				\
161   (DST)[2] = _tmp[2];				\
162   (DST)[3] = _tmp[3];				\
163} while (0)
164
165
166
167#define COPY_SZ_4V(DST, SZ, SRC) 		\
168do {						\
169   switch (SZ) {				\
170   case 4: (DST)[3] = (SRC)[3];			\
171   case 3: (DST)[2] = (SRC)[2];			\
172   case 2: (DST)[1] = (SRC)[1];			\
173   case 1: (DST)[0] = (SRC)[0];			\
174   }  						\
175} while(0)
176
177#define COPY_CLEAN_4V(DST, SZ, SRC) 		\
178do {						\
179      ASSIGN_4V( DST, 0, 0, 0, 1 );		\
180      COPY_SZ_4V( DST, SZ, SRC );		\
181} while (0)
182
183#define SUB_4V( DST, SRCA, SRCB )		\
184do {						\
185      (DST)[0] = (SRCA)[0] - (SRCB)[0];		\
186      (DST)[1] = (SRCA)[1] - (SRCB)[1];		\
187      (DST)[2] = (SRCA)[2] - (SRCB)[2];		\
188      (DST)[3] = (SRCA)[3] - (SRCB)[3];		\
189} while (0)
190
191#define ADD_4V( DST, SRCA, SRCB )		\
192do {						\
193      (DST)[0] = (SRCA)[0] + (SRCB)[0];		\
194      (DST)[1] = (SRCA)[1] + (SRCB)[1];		\
195      (DST)[2] = (SRCA)[2] + (SRCB)[2];		\
196      (DST)[3] = (SRCA)[3] + (SRCB)[3];		\
197} while (0)
198
199#define SCALE_4V( DST, SRCA, SRCB )		\
200do {						\
201      (DST)[0] = (SRCA)[0] * (SRCB)[0];		\
202      (DST)[1] = (SRCA)[1] * (SRCB)[1];		\
203      (DST)[2] = (SRCA)[2] * (SRCB)[2];		\
204      (DST)[3] = (SRCA)[3] * (SRCB)[3];		\
205} while (0)
206
207#define ACC_4V( DST, SRC )			\
208do {						\
209      (DST)[0] += (SRC)[0];			\
210      (DST)[1] += (SRC)[1];			\
211      (DST)[2] += (SRC)[2];			\
212      (DST)[3] += (SRC)[3];			\
213} while (0)
214
215#define ACC_SCALE_4V( DST, SRCA, SRCB )		\
216do {						\
217      (DST)[0] += (SRCA)[0] * (SRCB)[0];	\
218      (DST)[1] += (SRCA)[1] * (SRCB)[1];	\
219      (DST)[2] += (SRCA)[2] * (SRCB)[2];	\
220      (DST)[3] += (SRCA)[3] * (SRCB)[3];	\
221} while (0)
222
223#define ACC_SCALE_SCALAR_4V( DST, S, SRCB )	\
224do {						\
225      (DST)[0] += S * (SRCB)[0];		\
226      (DST)[1] += S * (SRCB)[1];		\
227      (DST)[2] += S * (SRCB)[2];		\
228      (DST)[3] += S * (SRCB)[3];		\
229} while (0)
230
231#define SCALE_SCALAR_4V( DST, S, SRCB )		\
232do {						\
233      (DST)[0] = S * (SRCB)[0];			\
234      (DST)[1] = S * (SRCB)[1];			\
235      (DST)[2] = S * (SRCB)[2];			\
236      (DST)[3] = S * (SRCB)[3];			\
237} while (0)
238
239
240#define SELF_SCALE_SCALAR_4V( DST, S )		\
241do {						\
242      (DST)[0] *= S;				\
243      (DST)[1] *= S;				\
244      (DST)[2] *= S;				\
245      (DST)[3] *= S;				\
246} while (0)
247
248
249/*
250 * Similarly for 3-vectors.
251 */
252#define SUB_3V( DST, SRCA, SRCB )		\
253do {						\
254      (DST)[0] = (SRCA)[0] - (SRCB)[0];		\
255      (DST)[1] = (SRCA)[1] - (SRCB)[1];		\
256      (DST)[2] = (SRCA)[2] - (SRCB)[2];		\
257} while (0)
258
259#define ADD_3V( DST, SRCA, SRCB )		\
260do {						\
261      (DST)[0] = (SRCA)[0] + (SRCB)[0];		\
262      (DST)[1] = (SRCA)[1] + (SRCB)[1];		\
263      (DST)[2] = (SRCA)[2] + (SRCB)[2];		\
264} while (0)
265
266#define SCALE_3V( DST, SRCA, SRCB )		\
267do {						\
268      (DST)[0] = (SRCA)[0] * (SRCB)[0];		\
269      (DST)[1] = (SRCA)[1] * (SRCB)[1];		\
270      (DST)[2] = (SRCA)[2] * (SRCB)[2];		\
271} while (0)
272
273#define SELF_SCALE_3V( DST, SRC )		\
274do {						\
275      (DST)[0] *= (SRC)[0];			\
276      (DST)[1] *= (SRC)[1];			\
277      (DST)[2] *= (SRC)[2];			\
278} while (0)
279
280#define ACC_3V( DST, SRC )			\
281do {						\
282      (DST)[0] += (SRC)[0];			\
283      (DST)[1] += (SRC)[1];			\
284      (DST)[2] += (SRC)[2];			\
285} while (0)
286
287#define ACC_SCALE_3V( DST, SRCA, SRCB )		\
288do {						\
289      (DST)[0] += (SRCA)[0] * (SRCB)[0];	\
290      (DST)[1] += (SRCA)[1] * (SRCB)[1];	\
291      (DST)[2] += (SRCA)[2] * (SRCB)[2];	\
292} while (0)
293
294#define SCALE_SCALAR_3V( DST, S, SRCB ) 	\
295do {						\
296      (DST)[0] = S * (SRCB)[0];			\
297      (DST)[1] = S * (SRCB)[1];			\
298      (DST)[2] = S * (SRCB)[2];			\
299} while (0)
300
301#define ACC_SCALE_SCALAR_3V( DST, S, SRCB )	\
302do {						\
303      (DST)[0] += S * (SRCB)[0];		\
304      (DST)[1] += S * (SRCB)[1];		\
305      (DST)[2] += S * (SRCB)[2];		\
306} while (0)
307
308#define SELF_SCALE_SCALAR_3V( DST, S )		\
309do {						\
310      (DST)[0] *= S;				\
311      (DST)[1] *= S;				\
312      (DST)[2] *= S;				\
313} while (0)
314
315#define ACC_SCALAR_3V( DST, S ) 		\
316do {						\
317      (DST)[0] += S;				\
318      (DST)[1] += S;				\
319      (DST)[2] += S;				\
320} while (0)
321
322/* And also for 2-vectors
323 */
324#define SUB_2V( DST, SRCA, SRCB )		\
325do {						\
326      (DST)[0] = (SRCA)[0] - (SRCB)[0];		\
327      (DST)[1] = (SRCA)[1] - (SRCB)[1];		\
328} while (0)
329
330#define ADD_2V( DST, SRCA, SRCB )		\
331do {						\
332      (DST)[0] = (SRCA)[0] + (SRCB)[0];		\
333      (DST)[1] = (SRCA)[1] + (SRCB)[1];		\
334} while (0)
335
336#define SCALE_2V( DST, SRCA, SRCB )		\
337do {						\
338      (DST)[0] = (SRCA)[0] * (SRCB)[0];		\
339      (DST)[1] = (SRCA)[1] * (SRCB)[1];		\
340} while (0)
341
342#define ACC_2V( DST, SRC )			\
343do {						\
344      (DST)[0] += (SRC)[0];			\
345      (DST)[1] += (SRC)[1];			\
346} while (0)
347
348#define ACC_SCALE_2V( DST, SRCA, SRCB )		\
349do {						\
350      (DST)[0] += (SRCA)[0] * (SRCB)[0];	\
351      (DST)[1] += (SRCA)[1] * (SRCB)[1];	\
352} while (0)
353
354#define SCALE_SCALAR_2V( DST, S, SRCB ) 	\
355do {						\
356      (DST)[0] = S * (SRCB)[0];			\
357      (DST)[1] = S * (SRCB)[1];			\
358} while (0)
359
360#define ACC_SCALE_SCALAR_2V( DST, S, SRCB )	\
361do {						\
362      (DST)[0] += S * (SRCB)[0];		\
363      (DST)[1] += S * (SRCB)[1];		\
364} while (0)
365
366#define SELF_SCALE_SCALAR_2V( DST, S )		\
367do {						\
368      (DST)[0] *= S;				\
369      (DST)[1] *= S;				\
370} while (0)
371
372#define ACC_SCALAR_2V( DST, S ) 		\
373do {						\
374      (DST)[0] += S;				\
375      (DST)[1] += S;				\
376} while (0)
377
378
379
380/* Assign scalers to short vectors: */
381#define ASSIGN_2V( V, V0, V1 )	\
382do { 				\
383    V[0] = V0; 			\
384    V[1] = V1; 			\
385} while(0)
386
387#define ASSIGN_3V( V, V0, V1, V2 )	\
388do { 				 	\
389    V[0] = V0; 				\
390    V[1] = V1; 				\
391    V[2] = V2; 				\
392} while(0)
393
394#define ASSIGN_4V( V, V0, V1, V2, V3 ) 		\
395do { 						\
396    V[0] = V0;					\
397    V[1] = V1;					\
398    V[2] = V2;					\
399    V[3] = V3; 					\
400} while(0)
401
402
403
404
405/* Absolute value (for Int, Float, Double): */
406#define ABSI(X)  ((X) < 0 ? -(X) : (X))
407#define ABSF(X)  ((X) < 0.0F ? -(X) : (X))
408#define ABSD(X)  ((X) < 0.0 ? -(X) : (X))
409
410
411
412/* Round a floating-point value to the nearest integer: */
413#define ROUNDF(X)  ( (X)<0.0F ? ((GLint) ((X)-0.5F)) : ((GLint) ((X)+0.5F)) )
414
415
416/* Compute ceiling of integer quotient of A divided by B: */
417#define CEILING( A, B )  ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
418
419
420/* Clamp X to [MIN,MAX]: */
421#define CLAMP( X, MIN, MAX )  ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
422
423/* Assign X to CLAMP(X, MIN, MAX) */
424#define CLAMP_SELF(x, mn, mx)  \
425   ( (x)<(mn) ? ((x) = (mn)) : ((x)>(mx) ? ((x)=(mx)) : (x)) )
426
427
428
429/* Min of two values: */
430#define MIN2( A, B )   ( (A)<(B) ? (A) : (B) )
431
432/* MAX of two values: */
433#define MAX2( A, B )   ( (A)>(B) ? (A) : (B) )
434
435/* Dot product of two 2-element vectors */
436#define DOT2( a, b )  ( (a)[0]*(b)[0] + (a)[1]*(b)[1] )
437
438/* Dot product of two 3-element vectors */
439#define DOT3( a, b )  ( (a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] )
440
441/* Dot product of two 4-element vectors */
442#define DOT4( a, b )  ( (a)[0]*(b)[0] + (a)[1]*(b)[1] + \
443			(a)[2]*(b)[2] + (a)[3]*(b)[3] )
444
445#define DOT4V(v,a,b,c,d) (v[0]*(a) + v[1]*(b) + v[2]*(c) + v[3]*(d))
446
447
448#define CROSS3(n, u, v) 			\
449do {						\
450   (n)[0] = (u)[1]*(v)[2] - (u)[2]*(v)[1]; 	\
451   (n)[1] = (u)[2]*(v)[0] - (u)[0]*(v)[2]; 	\
452   (n)[2] = (u)[0]*(v)[1] - (u)[1]*(v)[0];	\
453} while (0)
454
455
456
457/* Generic color packing macros
458 */
459
460#define PACK_COLOR_8888( a, b, c, d )					\
461   (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
462
463#define PACK_COLOR_888( a, b, c )					\
464   (((a) << 16) | ((b) << 8) | (c))
465
466#define PACK_COLOR_565( a, b, c )					\
467   ((((a) & 0xf8) << 8) | (((b) & 0xfc) << 3) | (((c) & 0xf8) >> 3))
468
469#define PACK_COLOR_1555( a, b, c, d )					\
470   ((((b) & 0xf8) << 7) | (((c) & 0xf8) << 2) | (((d) & 0xf8) >> 3) |	\
471    ((a) ? 0x8000 : 0))
472
473#define PACK_COLOR_4444( a, b, c, d )					\
474   ((((a) & 0xf0) << 8) | (((b) & 0xf0) << 4) | ((c) & 0xf0) | ((d) >> 4))
475
476#define PACK_COLOR_88( a, b )						\
477   (((a) << 8) | (b))
478
479#define PACK_COLOR_332( a, b, c )					\
480   (((a) & 0xe0) | (((b) & 0xe0) >> 3) | (((c) & 0xc0) >> 6))
481
482
483#endif
484