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(B)>(MIN)>>>>>><>>>>>><>63),(1><63),(1> |