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 723