macros.h revision ad2ac216fa0cbebc36530bf9e5256e902710b892
1/* $Id: macros.h,v 1.15 2000/11/24 10:25:05 keithw Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version:  3.5
6 *
7 * Copyright (C) 1999-2000  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_T(p, t, i)  (p = (t *)((GLubyte *)p + i))
76
77
78#define ZERO_2V( DST )	(DST)[0] = (DST)[1] = 0
79#define ZERO_3V( DST )	(DST)[0] = (DST)[1] = (DST)[2] = 0
80#define ZERO_4V( DST )	(DST)[0] = (DST)[1] = (DST)[2] = (DST)[3] = 0
81
82
83/* Copy short vectors: */
84#define COPY_2V( DST, SRC )			\
85do {						\
86   (DST)[0] = (SRC)[0];				\
87   (DST)[1] = (SRC)[1];				\
88} while (0)
89
90#define COPY_3V( DST, SRC )			\
91do {						\
92   (DST)[0] = (SRC)[0];				\
93   (DST)[1] = (SRC)[1];				\
94   (DST)[2] = (SRC)[2];				\
95} while (0)
96
97#define COPY_4V( DST, SRC )			\
98do {						\
99   (DST)[0] = (SRC)[0];				\
100   (DST)[1] = (SRC)[1];				\
101   (DST)[2] = (SRC)[2];				\
102   (DST)[3] = (SRC)[3];				\
103} while (0)
104
105#define COPY_4UBV(DST, SRC)			\
106do {						\
107   if (sizeof(GLuint)==4*sizeof(GLubyte)) {	\
108      *((GLuint*)(DST)) = *((GLuint*)(SRC));	\
109   }						\
110   else {					\
111      (DST)[0] = (SRC)[0];			\
112      (DST)[1] = (SRC)[1];			\
113      (DST)[2] = (SRC)[2];			\
114      (DST)[3] = (SRC)[3];			\
115   }						\
116} while (0)
117
118
119#define COPY_2FV( DST, SRC )			\
120do {						\
121   const GLfloat *_tmp = (SRC);			\
122   (DST)[0] = _tmp[0];				\
123   (DST)[1] = _tmp[1];				\
124} while (0)
125
126#define COPY_3FV( DST, SRC )			\
127do {						\
128   const GLfloat *_tmp = (SRC);			\
129   (DST)[0] = _tmp[0];				\
130   (DST)[1] = _tmp[1];				\
131   (DST)[2] = _tmp[2];				\
132} while (0)
133
134#define COPY_4FV( DST, SRC )			\
135do {						\
136   const GLfloat *_tmp = (SRC);			\
137   (DST)[0] = _tmp[0];				\
138   (DST)[1] = _tmp[1];				\
139   (DST)[2] = _tmp[2];				\
140   (DST)[3] = _tmp[3];				\
141} while (0)
142
143
144
145#define COPY_SZ_4V(DST, SZ, SRC) 		\
146do {						\
147   switch (SZ) {				\
148   case 4: (DST)[3] = (SRC)[3];			\
149   case 3: (DST)[2] = (SRC)[2];			\
150   case 2: (DST)[1] = (SRC)[1];			\
151   case 1: (DST)[0] = (SRC)[0];			\
152   }  						\
153} while(0)
154
155#define COPY_CLEAN_4V(DST, SZ, SRC) 		\
156do {						\
157      ASSIGN_4V( DST, 0, 0, 0, 1 );		\
158      COPY_SZ_4V( DST, SZ, SRC );		\
159} while (0)
160
161#define SUB_4V( DST, SRCA, SRCB )		\
162do {						\
163      (DST)[0] = (SRCA)[0] - (SRCB)[0];		\
164      (DST)[1] = (SRCA)[1] - (SRCB)[1];		\
165      (DST)[2] = (SRCA)[2] - (SRCB)[2];		\
166      (DST)[3] = (SRCA)[3] - (SRCB)[3];		\
167} while (0)
168
169#define ADD_4V( DST, SRCA, SRCB )		\
170do {						\
171      (DST)[0] = (SRCA)[0] + (SRCB)[0];		\
172      (DST)[1] = (SRCA)[1] + (SRCB)[1];		\
173      (DST)[2] = (SRCA)[2] + (SRCB)[2];		\
174      (DST)[3] = (SRCA)[3] + (SRCB)[3];		\
175} while (0)
176
177#define SCALE_4V( DST, SRCA, SRCB )		\
178do {						\
179      (DST)[0] = (SRCA)[0] * (SRCB)[0];		\
180      (DST)[1] = (SRCA)[1] * (SRCB)[1];		\
181      (DST)[2] = (SRCA)[2] * (SRCB)[2];		\
182      (DST)[3] = (SRCA)[3] * (SRCB)[3];		\
183} while (0)
184
185#define ACC_4V( DST, SRC )			\
186do {						\
187      (DST)[0] += (SRC)[0];			\
188      (DST)[1] += (SRC)[1];			\
189      (DST)[2] += (SRC)[2];			\
190      (DST)[3] += (SRC)[3];			\
191} while (0)
192
193#define ACC_SCALE_4V( DST, SRCA, SRCB )		\
194do {						\
195      (DST)[0] += (SRCA)[0] * (SRCB)[0];	\
196      (DST)[1] += (SRCA)[1] * (SRCB)[1];	\
197      (DST)[2] += (SRCA)[2] * (SRCB)[2];	\
198      (DST)[3] += (SRCA)[3] * (SRCB)[3];	\
199} while (0)
200
201#define ACC_SCALE_SCALAR_4V( DST, S, SRCB )	\
202do {						\
203      (DST)[0] += S * (SRCB)[0];		\
204      (DST)[1] += S * (SRCB)[1];		\
205      (DST)[2] += S * (SRCB)[2];		\
206      (DST)[3] += S * (SRCB)[3];		\
207} while (0)
208
209#define SCALE_SCALAR_4V( DST, S, SRCB )		\
210do {						\
211      (DST)[0] = S * (SRCB)[0];			\
212      (DST)[1] = S * (SRCB)[1];			\
213      (DST)[2] = S * (SRCB)[2];			\
214      (DST)[3] = S * (SRCB)[3];			\
215} while (0)
216
217
218#define SELF_SCALE_SCALAR_4V( DST, S )		\
219do {						\
220      (DST)[0] *= S;				\
221      (DST)[1] *= S;				\
222      (DST)[2] *= S;				\
223      (DST)[3] *= S;				\
224} while (0)
225
226
227/*
228 * Similarly for 3-vectors.
229 */
230#define SUB_3V( DST, SRCA, SRCB )		\
231do {						\
232      (DST)[0] = (SRCA)[0] - (SRCB)[0];		\
233      (DST)[1] = (SRCA)[1] - (SRCB)[1];		\
234      (DST)[2] = (SRCA)[2] - (SRCB)[2];		\
235} while (0)
236
237#define ADD_3V( DST, SRCA, SRCB )		\
238do {						\
239      (DST)[0] = (SRCA)[0] + (SRCB)[0];		\
240      (DST)[1] = (SRCA)[1] + (SRCB)[1];		\
241      (DST)[2] = (SRCA)[2] + (SRCB)[2];		\
242} while (0)
243
244#define SCALE_3V( DST, SRCA, SRCB )		\
245do {						\
246      (DST)[0] = (SRCA)[0] * (SRCB)[0];		\
247      (DST)[1] = (SRCA)[1] * (SRCB)[1];		\
248      (DST)[2] = (SRCA)[2] * (SRCB)[2];		\
249} while (0)
250
251#define ACC_3V( DST, SRC )			\
252do {						\
253      (DST)[0] += (SRC)[0];			\
254      (DST)[1] += (SRC)[1];			\
255      (DST)[2] += (SRC)[2];			\
256} while (0)
257
258#define ACC_SCALE_3V( DST, SRCA, SRCB )		\
259do {						\
260      (DST)[0] += (SRCA)[0] * (SRCB)[0];	\
261      (DST)[1] += (SRCA)[1] * (SRCB)[1];	\
262      (DST)[2] += (SRCA)[2] * (SRCB)[2];	\
263} while (0)
264
265#define SCALE_SCALAR_3V( DST, S, SRCB ) 	\
266do {						\
267      (DST)[0] = S * (SRCB)[0];			\
268      (DST)[1] = S * (SRCB)[1];			\
269      (DST)[2] = S * (SRCB)[2];			\
270} while (0)
271
272#define ACC_SCALE_SCALAR_3V( DST, S, SRCB )	\
273do {						\
274      (DST)[0] += S * (SRCB)[0];		\
275      (DST)[1] += S * (SRCB)[1];		\
276      (DST)[2] += S * (SRCB)[2];		\
277} while (0)
278
279#define SELF_SCALE_SCALAR_3V( DST, S )		\
280do {						\
281      (DST)[0] *= S;				\
282      (DST)[1] *= S;				\
283      (DST)[2] *= S;				\
284} while (0)
285
286#define ACC_SCALAR_3V( DST, S ) 		\
287do {						\
288      (DST)[0] += S;				\
289      (DST)[1] += S;				\
290      (DST)[2] += S;				\
291} while (0)
292
293/* And also for 2-vectors
294 */
295#define SUB_2V( DST, SRCA, SRCB )		\
296do {						\
297      (DST)[0] = (SRCA)[0] - (SRCB)[0];		\
298      (DST)[1] = (SRCA)[1] - (SRCB)[1];		\
299} while (0)
300
301#define ADD_2V( DST, SRCA, SRCB )		\
302do {						\
303      (DST)[0] = (SRCA)[0] + (SRCB)[0];		\
304      (DST)[1] = (SRCA)[1] + (SRCB)[1];		\
305} while (0)
306
307#define SCALE_2V( DST, SRCA, SRCB )		\
308do {						\
309      (DST)[0] = (SRCA)[0] * (SRCB)[0];		\
310      (DST)[1] = (SRCA)[1] * (SRCB)[1];		\
311} while (0)
312
313#define ACC_2V( DST, SRC )			\
314do {						\
315      (DST)[0] += (SRC)[0];			\
316      (DST)[1] += (SRC)[1];			\
317} while (0)
318
319#define ACC_SCALE_2V( DST, SRCA, SRCB )		\
320do {						\
321      (DST)[0] += (SRCA)[0] * (SRCB)[0];	\
322      (DST)[1] += (SRCA)[1] * (SRCB)[1];	\
323} while (0)
324
325#define SCALE_SCALAR_2V( DST, S, SRCB ) 	\
326do {						\
327      (DST)[0] = S * (SRCB)[0];			\
328      (DST)[1] = S * (SRCB)[1];			\
329} while (0)
330
331#define ACC_SCALE_SCALAR_2V( DST, S, SRCB )	\
332do {						\
333      (DST)[0] += S * (SRCB)[0];		\
334      (DST)[1] += S * (SRCB)[1];		\
335} while (0)
336
337#define SELF_SCALE_SCALAR_2V( DST, S )		\
338do {						\
339      (DST)[0] *= S;				\
340      (DST)[1] *= S;				\
341} while (0)
342
343#define ACC_SCALAR_2V( DST, S ) 		\
344do {						\
345      (DST)[0] += S;				\
346      (DST)[1] += S;				\
347} while (0)
348
349
350
351/* Assign scalers to short vectors: */
352#define ASSIGN_2V( V, V0, V1 )	\
353do { 				\
354    V[0] = V0; 			\
355    V[1] = V1; 			\
356} while(0)
357
358#define ASSIGN_3V( V, V0, V1, V2 )	\
359do { 				 	\
360    V[0] = V0; 				\
361    V[1] = V1; 				\
362    V[2] = V2; 				\
363} while(0)
364
365#define ASSIGN_4V( V, V0, V1, V2, V3 ) 		\
366do { 						\
367    V[0] = V0;					\
368    V[1] = V1;					\
369    V[2] = V2;					\
370    V[3] = V3; 					\
371} while(0)
372
373
374
375
376/* Absolute value (for Int, Float, Double): */
377#define ABSI(X)  ((X) < 0 ? -(X) : (X))
378#define ABSF(X)  ((X) < 0.0F ? -(X) : (X))
379#define ABSD(X)  ((X) < 0.0 ? -(X) : (X))
380
381
382
383/* Round a floating-point value to the nearest integer: */
384#define ROUNDF(X)  ( (X)<0.0F ? ((GLint) ((X)-0.5F)) : ((GLint) ((X)+0.5F)) )
385
386
387/* Compute ceiling of integer quotient of A divided by B: */
388#define CEILING( A, B )  ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
389
390
391/* Clamp X to [MIN,MAX]: */
392#define CLAMP( X, MIN, MAX )  ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
393
394/* Assign X to CLAMP(X, MIN, MAX) */
395#define CLAMP_SELF(x, mn, mx)  \
396   ( (x)<(mn) ? ((x) = (mn)) : ((x)>(mx) ? ((x)=(mx)) : (x)) )
397
398
399
400/* Min of two values: */
401#define MIN2( A, B )   ( (A)<(B) ? (A) : (B) )
402
403/* MAX of two values: */
404#define MAX2( A, B )   ( (A)>(B) ? (A) : (B) )
405
406/* Dot product of two 2-element vectors */
407#define DOT2( a, b )  ( (a)[0]*(b)[0] + (a)[1]*(b)[1] )
408
409/* Dot product of two 3-element vectors */
410#define DOT3( a, b )  ( (a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] )
411
412/* Dot product of two 4-element vectors */
413#define DOT4( a, b )  ( (a)[0]*(b)[0] + (a)[1]*(b)[1] + \
414			(a)[2]*(b)[2] + (a)[3]*(b)[3] )
415
416#define DOT4V(v,a,b,c,d) (v[0]*(a) + v[1]*(b) + v[2]*(c) + v[3]*(d))
417
418
419#define CROSS3(n, u, v) 			\
420do {						\
421   (n)[0] = (u)[1]*(v)[2] - (u)[2]*(v)[1]; 	\
422   (n)[1] = (u)[2]*(v)[0] - (u)[0]*(v)[2]; 	\
423   (n)[2] = (u)[0]*(v)[1] - (u)[1]*(v)[0];	\
424} while (0)
425
426
427#endif
428