1 /** 2 * \file macros.h 3 * A collection of useful macros. 4 */ 5 6 /* 7 * Mesa 3-D graphics library 8 * 9 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 10 * 11 * Permission is hereby granted, free of charge, to any person obtaining a 12 * copy of this software and associated documentation files (the "Software"), 13 * to deal in the Software without restriction, including without limitation 14 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 15 * and/or sell copies of the Software, and to permit persons to whom the 16 * Software is furnished to do so, subject to the following conditions: 17 * 18 * The above copyright notice and this permission notice shall be included 19 * in all copies or substantial portions of the Software. 20 * 21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 24 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 25 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 26 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 27 * 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 to GLfloat while preserving zero */ 58 #define BYTE_TO_FLOATZ(B) ((B) == 0 ? 0.0F : BYTE_TO_FLOAT(B)) 59 60 61 /** Convert GLbyte in [-128,127] to GLfloat in [-1.0,1.0], texture/fb data */ 62 #define BYTE_TO_FLOAT_TEX(B) ((B) == -128 ? -1.0F : (B) * (1.0F/127.0F)) 63 64 /** Convert GLfloat in [-1.0,1.0] to GLbyte in [-128,127], texture/fb data */ 65 #define FLOAT_TO_BYTE_TEX(X) CLAMP( (GLint) (127.0F * (X)), -128, 127 ) 66 67 /** Convert GLushort in [0,65535] to GLfloat in [0.0,1.0] */ 68 #define USHORT_TO_FLOAT(S) ((GLfloat) (S) * (1.0F / 65535.0F)) 69 70 /** Convert GLfloat in [0.0,1.0] to GLushort in [0, 65535] */ 71 #define FLOAT_TO_USHORT(X) ((GLuint) ((X) * 65535.0F)) 72 73 74 /** Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0] */ 75 #define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F)) 76 77 /** Convert GLfloat in [-1.0,1.0] to GLshort in [-32768,32767] */ 78 #define FLOAT_TO_SHORT(X) ( (((GLint) (65535.0F * (X))) - 1) / 2 ) 79 80 /** Convert GLshort to GLfloat while preserving zero */ 81 #define SHORT_TO_FLOATZ(S) ((S) == 0 ? 0.0F : SHORT_TO_FLOAT(S)) 82 83 84 /** Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0], texture/fb data */ 85 #define SHORT_TO_FLOAT_TEX(S) ((S) == -32768 ? -1.0F : (S) * (1.0F/32767.0F)) 86 87 /** Convert GLfloat in [-1.0,1.0] to GLshort in [-32768,32767], texture/fb data */ 88 #define FLOAT_TO_SHORT_TEX(X) ( (GLint) (32767.0F * (X)) ) 89 90 91 /** Convert GLuint in [0,4294967295] to GLfloat in [0.0,1.0] */ 92 #define UINT_TO_FLOAT(U) ((GLfloat) ((U) * (1.0F / 4294967295.0))) 93 94 /** Convert GLfloat in [0.0,1.0] to GLuint in [0,4294967295] */ 95 #define FLOAT_TO_UINT(X) ((GLuint) ((X) * 4294967295.0)) 96 97 98 /** Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0] */ 99 #define INT_TO_FLOAT(I) ((GLfloat) ((2.0F * (I) + 1.0F) * (1.0F/4294967294.0))) 100 101 /** Convert GLfloat in [-1.0,1.0] to GLint in [-2147483648,2147483647] */ 102 /* causes overflow: 103 #define FLOAT_TO_INT(X) ( (((GLint) (4294967294.0 * (X))) - 1) / 2 ) 104 */ 105 /* a close approximation: */ 106 #define FLOAT_TO_INT(X) ( (GLint) (2147483647.0 * (X)) ) 107 108 /** Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0], texture/fb data */ 109 #define INT_TO_FLOAT_TEX(I) ((I) == -2147483648 ? -1.0F : (I) * (1.0F/2147483647.0)) 110 111 /** Convert GLfloat in [-1.0,1.0] to GLint in [-2147483648,2147483647], texture/fb data */ 112 #define FLOAT_TO_INT_TEX(X) ( (GLint) (2147483647.0 * (X)) ) 113 114 115 #define BYTE_TO_UBYTE(b) ((GLubyte) ((b) < 0 ? 0 : (GLubyte) (b))) 116 #define SHORT_TO_UBYTE(s) ((GLubyte) ((s) < 0 ? 0 : (GLubyte) ((s) >> 7))) 117 #define USHORT_TO_UBYTE(s) ((GLubyte) ((s) >> 8)) 118 #define INT_TO_UBYTE(i) ((GLubyte) ((i) < 0 ? 0 : (GLubyte) ((i) >> 23))) 119 #define UINT_TO_UBYTE(i) ((GLubyte) ((i) >> 24)) 120 121 122 #define BYTE_TO_USHORT(b) ((b) < 0 ? 0 : ((GLushort) (((b) * 65535) / 255))) 123 #define UBYTE_TO_USHORT(b) (((GLushort) (b) << 8) | (GLushort) (b)) 124 #define SHORT_TO_USHORT(s) ((s) < 0 ? 0 : ((GLushort) (((s) * 65535 / 32767)))) 125 #define INT_TO_USHORT(i) ((i) < 0 ? 0 : ((GLushort) ((i) >> 15))) 126 #define UINT_TO_USHORT(i) ((i) < 0 ? 0 : ((GLushort) ((i) >> 16))) 127 #define UNCLAMPED_FLOAT_TO_USHORT(us, f) \ 128 us = ( (GLushort) F_TO_I( CLAMP((f), 0.0F, 1.0F) * 65535.0F) ) 129 #define CLAMPED_FLOAT_TO_USHORT(us, f) \ 130 us = ( (GLushort) F_TO_I( (f) * 65535.0F) ) 131 132 #define UNCLAMPED_FLOAT_TO_SHORT(s, f) \ 133 s = ( (GLshort) F_TO_I( CLAMP((f), -1.0F, 1.0F) * 32767.0F) ) 134 135 /*** 136 *** UNCLAMPED_FLOAT_TO_UBYTE: clamp float to [0,1] and map to ubyte in [0,255] 137 *** CLAMPED_FLOAT_TO_UBYTE: map float known to be in [0,1] to ubyte in [0,255] 138 ***/ 139 #ifndef DEBUG 140 /* This function/macro is sensitive to precision. Test very carefully 141 * if you change it! 142 */ 143 #define UNCLAMPED_FLOAT_TO_UBYTE(UB, FLT) \ 144 do { \ 145 fi_type __tmp; \ 146 __tmp.f = (FLT); \ 147 if (__tmp.i < 0) \ 148 UB = (GLubyte) 0; \ 149 else if (__tmp.i >= IEEE_ONE) \ 150 UB = (GLubyte) 255; \ 151 else { \ 152 __tmp.f = __tmp.f * (255.0F/256.0F) + 32768.0F; \ 153 UB = (GLubyte) __tmp.i; \ 154 } \ 155 } while (0) 156 #define CLAMPED_FLOAT_TO_UBYTE(UB, FLT) \ 157 do { \ 158 fi_type __tmp; \ 159 __tmp.f = (FLT) * (255.0F/256.0F) + 32768.0F; \ 160 UB = (GLubyte) __tmp.i; \ 161 } while (0) 162 #else 163 #define UNCLAMPED_FLOAT_TO_UBYTE(ub, f) \ 164 ub = ((GLubyte) F_TO_I(CLAMP((f), 0.0F, 1.0F) * 255.0F)) 165 #define CLAMPED_FLOAT_TO_UBYTE(ub, f) \ 166 ub = ((GLubyte) F_TO_I((f) * 255.0F)) 167 #endif 168 169 static inline GLfloat INT_AS_FLT(GLint i) 170 { 171 fi_type tmp; 172 tmp.i = i; 173 return tmp.f; 174 } 175 176 static inline GLfloat UINT_AS_FLT(GLuint u) 177 { 178 fi_type tmp; 179 tmp.u = u; 180 return tmp.f; 181 } 182 183 static inline unsigned FLT_AS_UINT(float f) 184 { 185 fi_type tmp; 186 tmp.f = f; 187 return tmp.u; 188 } 189 190 /** 191 * Convert a floating point value to an unsigned fixed point value. 192 * 193 * \param frac_bits The number of bits used to store the fractional part. 194 */ 195 static inline uint32_t 196 U_FIXED(float value, uint32_t frac_bits) 197 { 198 value *= (1 << frac_bits); 199 return value < 0.0f ? 0 : (uint32_t) value; 200 } 201 202 /** 203 * Convert a floating point value to an signed fixed point value. 204 * 205 * \param frac_bits The number of bits used to store the fractional part. 206 */ 207 static inline int32_t 208 S_FIXED(float value, uint32_t frac_bits) 209 { 210 return (int32_t) (value * (1 << frac_bits)); 211 } 212 /*@}*/ 213 214 215 /** Stepping a GLfloat pointer by a byte stride */ 216 #define STRIDE_F(p, i) (p = (GLfloat *)((GLubyte *)p + i)) 217 /** Stepping a GLuint pointer by a byte stride */ 218 #define STRIDE_UI(p, i) (p = (GLuint *)((GLubyte *)p + i)) 219 /** Stepping a GLubyte[4] pointer by a byte stride */ 220 #define STRIDE_4UB(p, i) (p = (GLubyte (*)[4])((GLubyte *)p + i)) 221 /** Stepping a GLfloat[4] pointer by a byte stride */ 222 #define STRIDE_4F(p, i) (p = (GLfloat (*)[4])((GLubyte *)p + i)) 223 /** Stepping a \p t pointer by a byte stride */ 224 #define STRIDE_T(p, t, i) (p = (t)((GLubyte *)p + i)) 225 226 227 /**********************************************************************/ 228 /** \name 4-element vector operations */ 229 /*@{*/ 230 231 /** Zero */ 232 #define ZERO_4V( DST ) (DST)[0] = (DST)[1] = (DST)[2] = (DST)[3] = 0 233 234 /** Test for equality */ 235 #define TEST_EQ_4V(a,b) ((a)[0] == (b)[0] && \ 236 (a)[1] == (b)[1] && \ 237 (a)[2] == (b)[2] && \ 238 (a)[3] == (b)[3]) 239 240 /** Test for equality (unsigned bytes) */ 241 static inline GLboolean 242 TEST_EQ_4UBV(const GLubyte a[4], const GLubyte b[4]) 243 { 244 #if defined(__i386__) 245 return *((const GLuint *) a) == *((const GLuint *) b); 246 #else 247 return TEST_EQ_4V(a, b); 248 #endif 249 } 250 251 252 /** Copy a 4-element vector */ 253 #define COPY_4V( DST, SRC ) \ 254 do { \ 255 (DST)[0] = (SRC)[0]; \ 256 (DST)[1] = (SRC)[1]; \ 257 (DST)[2] = (SRC)[2]; \ 258 (DST)[3] = (SRC)[3]; \ 259 } while (0) 260 261 /** Copy a 4-element unsigned byte vector */ 262 static inline void 263 COPY_4UBV(GLubyte dst[4], const GLubyte src[4]) 264 { 265 #if defined(__i386__) 266 *((GLuint *) dst) = *((GLuint *) src); 267 #else 268 /* The GLuint cast might fail if DST or SRC are not dword-aligned (RISC) */ 269 COPY_4V(dst, src); 270 #endif 271 } 272 273 /** Copy a 4-element float vector */ 274 static inline void 275 COPY_4FV(GLfloat dst[4], const GLfloat src[4]) 276 { 277 /* memcpy seems to be most efficient */ 278 memcpy(dst, src, sizeof(GLfloat) * 4); 279 } 280 281 /** Copy \p SZ elements into a 4-element vector */ 282 #define COPY_SZ_4V(DST, SZ, SRC) \ 283 do { \ 284 switch (SZ) { \ 285 case 4: (DST)[3] = (SRC)[3]; \ 286 case 3: (DST)[2] = (SRC)[2]; \ 287 case 2: (DST)[1] = (SRC)[1]; \ 288 case 1: (DST)[0] = (SRC)[0]; \ 289 } \ 290 } while(0) 291 292 /** Copy \p SZ elements into a homegeneous (4-element) vector, giving 293 * default values to the remaining */ 294 #define COPY_CLEAN_4V(DST, SZ, SRC) \ 295 do { \ 296 ASSIGN_4V( DST, 0, 0, 0, 1 ); \ 297 COPY_SZ_4V( DST, SZ, SRC ); \ 298 } while (0) 299 300 /** Subtraction */ 301 #define SUB_4V( DST, SRCA, SRCB ) \ 302 do { \ 303 (DST)[0] = (SRCA)[0] - (SRCB)[0]; \ 304 (DST)[1] = (SRCA)[1] - (SRCB)[1]; \ 305 (DST)[2] = (SRCA)[2] - (SRCB)[2]; \ 306 (DST)[3] = (SRCA)[3] - (SRCB)[3]; \ 307 } while (0) 308 309 /** Addition */ 310 #define ADD_4V( DST, SRCA, SRCB ) \ 311 do { \ 312 (DST)[0] = (SRCA)[0] + (SRCB)[0]; \ 313 (DST)[1] = (SRCA)[1] + (SRCB)[1]; \ 314 (DST)[2] = (SRCA)[2] + (SRCB)[2]; \ 315 (DST)[3] = (SRCA)[3] + (SRCB)[3]; \ 316 } while (0) 317 318 /** Element-wise multiplication */ 319 #define SCALE_4V( DST, SRCA, SRCB ) \ 320 do { \ 321 (DST)[0] = (SRCA)[0] * (SRCB)[0]; \ 322 (DST)[1] = (SRCA)[1] * (SRCB)[1]; \ 323 (DST)[2] = (SRCA)[2] * (SRCB)[2]; \ 324 (DST)[3] = (SRCA)[3] * (SRCB)[3]; \ 325 } while (0) 326 327 /** In-place addition */ 328 #define ACC_4V( DST, SRC ) \ 329 do { \ 330 (DST)[0] += (SRC)[0]; \ 331 (DST)[1] += (SRC)[1]; \ 332 (DST)[2] += (SRC)[2]; \ 333 (DST)[3] += (SRC)[3]; \ 334 } while (0) 335 336 /** Element-wise multiplication and addition */ 337 #define ACC_SCALE_4V( DST, SRCA, SRCB ) \ 338 do { \ 339 (DST)[0] += (SRCA)[0] * (SRCB)[0]; \ 340 (DST)[1] += (SRCA)[1] * (SRCB)[1]; \ 341 (DST)[2] += (SRCA)[2] * (SRCB)[2]; \ 342 (DST)[3] += (SRCA)[3] * (SRCB)[3]; \ 343 } while (0) 344 345 /** In-place scalar multiplication and addition */ 346 #define ACC_SCALE_SCALAR_4V( DST, S, SRCB ) \ 347 do { \ 348 (DST)[0] += S * (SRCB)[0]; \ 349 (DST)[1] += S * (SRCB)[1]; \ 350 (DST)[2] += S * (SRCB)[2]; \ 351 (DST)[3] += S * (SRCB)[3]; \ 352 } while (0) 353 354 /** Scalar multiplication */ 355 #define SCALE_SCALAR_4V( DST, S, SRCB ) \ 356 do { \ 357 (DST)[0] = S * (SRCB)[0]; \ 358 (DST)[1] = S * (SRCB)[1]; \ 359 (DST)[2] = S * (SRCB)[2]; \ 360 (DST)[3] = S * (SRCB)[3]; \ 361 } while (0) 362 363 /** In-place scalar multiplication */ 364 #define SELF_SCALE_SCALAR_4V( DST, S ) \ 365 do { \ 366 (DST)[0] *= S; \ 367 (DST)[1] *= S; \ 368 (DST)[2] *= S; \ 369 (DST)[3] *= S; \ 370 } while (0) 371 372 /** Assignment */ 373 #define ASSIGN_4V( V, V0, V1, V2, V3 ) \ 374 do { \ 375 V[0] = V0; \ 376 V[1] = V1; \ 377 V[2] = V2; \ 378 V[3] = V3; \ 379 } while(0) 380 381 /*@}*/ 382 383 384 /**********************************************************************/ 385 /** \name 3-element vector operations*/ 386 /*@{*/ 387 388 /** Zero */ 389 #define ZERO_3V( DST ) (DST)[0] = (DST)[1] = (DST)[2] = 0 390 391 /** Test for equality */ 392 #define TEST_EQ_3V(a,b) \ 393 ((a)[0] == (b)[0] && \ 394 (a)[1] == (b)[1] && \ 395 (a)[2] == (b)[2]) 396 397 /** Copy a 3-element vector */ 398 #define COPY_3V( DST, SRC ) \ 399 do { \ 400 (DST)[0] = (SRC)[0]; \ 401 (DST)[1] = (SRC)[1]; \ 402 (DST)[2] = (SRC)[2]; \ 403 } while (0) 404 405 /** Copy a 3-element vector with cast */ 406 #define COPY_3V_CAST( DST, SRC, CAST ) \ 407 do { \ 408 (DST)[0] = (CAST)(SRC)[0]; \ 409 (DST)[1] = (CAST)(SRC)[1]; \ 410 (DST)[2] = (CAST)(SRC)[2]; \ 411 } while (0) 412 413 /** Copy a 3-element float vector */ 414 #define COPY_3FV( DST, SRC ) \ 415 do { \ 416 const GLfloat *_tmp = (SRC); \ 417 (DST)[0] = _tmp[0]; \ 418 (DST)[1] = _tmp[1]; \ 419 (DST)[2] = _tmp[2]; \ 420 } while (0) 421 422 /** Subtraction */ 423 #define SUB_3V( DST, SRCA, SRCB ) \ 424 do { \ 425 (DST)[0] = (SRCA)[0] - (SRCB)[0]; \ 426 (DST)[1] = (SRCA)[1] - (SRCB)[1]; \ 427 (DST)[2] = (SRCA)[2] - (SRCB)[2]; \ 428 } while (0) 429 430 /** Addition */ 431 #define ADD_3V( DST, SRCA, SRCB ) \ 432 do { \ 433 (DST)[0] = (SRCA)[0] + (SRCB)[0]; \ 434 (DST)[1] = (SRCA)[1] + (SRCB)[1]; \ 435 (DST)[2] = (SRCA)[2] + (SRCB)[2]; \ 436 } while (0) 437 438 /** In-place scalar multiplication */ 439 #define SCALE_3V( DST, SRCA, SRCB ) \ 440 do { \ 441 (DST)[0] = (SRCA)[0] * (SRCB)[0]; \ 442 (DST)[1] = (SRCA)[1] * (SRCB)[1]; \ 443 (DST)[2] = (SRCA)[2] * (SRCB)[2]; \ 444 } while (0) 445 446 /** In-place element-wise multiplication */ 447 #define SELF_SCALE_3V( DST, SRC ) \ 448 do { \ 449 (DST)[0] *= (SRC)[0]; \ 450 (DST)[1] *= (SRC)[1]; \ 451 (DST)[2] *= (SRC)[2]; \ 452 } while (0) 453 454 /** In-place addition */ 455 #define ACC_3V( DST, SRC ) \ 456 do { \ 457 (DST)[0] += (SRC)[0]; \ 458 (DST)[1] += (SRC)[1]; \ 459 (DST)[2] += (SRC)[2]; \ 460 } while (0) 461 462 /** Element-wise multiplication and addition */ 463 #define ACC_SCALE_3V( DST, SRCA, SRCB ) \ 464 do { \ 465 (DST)[0] += (SRCA)[0] * (SRCB)[0]; \ 466 (DST)[1] += (SRCA)[1] * (SRCB)[1]; \ 467 (DST)[2] += (SRCA)[2] * (SRCB)[2]; \ 468 } while (0) 469 470 /** Scalar multiplication */ 471 #define SCALE_SCALAR_3V( DST, S, SRCB ) \ 472 do { \ 473 (DST)[0] = S * (SRCB)[0]; \ 474 (DST)[1] = S * (SRCB)[1]; \ 475 (DST)[2] = S * (SRCB)[2]; \ 476 } while (0) 477 478 /** In-place scalar multiplication and addition */ 479 #define ACC_SCALE_SCALAR_3V( DST, S, SRCB ) \ 480 do { \ 481 (DST)[0] += S * (SRCB)[0]; \ 482 (DST)[1] += S * (SRCB)[1]; \ 483 (DST)[2] += S * (SRCB)[2]; \ 484 } while (0) 485 486 /** In-place scalar multiplication */ 487 #define SELF_SCALE_SCALAR_3V( DST, S ) \ 488 do { \ 489 (DST)[0] *= S; \ 490 (DST)[1] *= S; \ 491 (DST)[2] *= S; \ 492 } while (0) 493 494 /** In-place scalar addition */ 495 #define ACC_SCALAR_3V( DST, S ) \ 496 do { \ 497 (DST)[0] += S; \ 498 (DST)[1] += S; \ 499 (DST)[2] += S; \ 500 } while (0) 501 502 /** Assignment */ 503 #define ASSIGN_3V( V, V0, V1, V2 ) \ 504 do { \ 505 V[0] = V0; \ 506 V[1] = V1; \ 507 V[2] = V2; \ 508 } while(0) 509 510 /*@}*/ 511 512 513 /**********************************************************************/ 514 /** \name 2-element vector operations*/ 515 /*@{*/ 516 517 /** Zero */ 518 #define ZERO_2V( DST ) (DST)[0] = (DST)[1] = 0 519 520 /** Copy a 2-element vector */ 521 #define COPY_2V( DST, SRC ) \ 522 do { \ 523 (DST)[0] = (SRC)[0]; \ 524 (DST)[1] = (SRC)[1]; \ 525 } while (0) 526 527 /** Copy a 2-element vector with cast */ 528 #define COPY_2V_CAST( DST, SRC, CAST ) \ 529 do { \ 530 (DST)[0] = (CAST)(SRC)[0]; \ 531 (DST)[1] = (CAST)(SRC)[1]; \ 532 } while (0) 533 534 /** Copy a 2-element float vector */ 535 #define COPY_2FV( DST, SRC ) \ 536 do { \ 537 const GLfloat *_tmp = (SRC); \ 538 (DST)[0] = _tmp[0]; \ 539 (DST)[1] = _tmp[1]; \ 540 } while (0) 541 542 /** Subtraction */ 543 #define SUB_2V( DST, SRCA, SRCB ) \ 544 do { \ 545 (DST)[0] = (SRCA)[0] - (SRCB)[0]; \ 546 (DST)[1] = (SRCA)[1] - (SRCB)[1]; \ 547 } while (0) 548 549 /** Addition */ 550 #define ADD_2V( DST, SRCA, SRCB ) \ 551 do { \ 552 (DST)[0] = (SRCA)[0] + (SRCB)[0]; \ 553 (DST)[1] = (SRCA)[1] + (SRCB)[1]; \ 554 } while (0) 555 556 /** In-place scalar multiplication */ 557 #define SCALE_2V( DST, SRCA, SRCB ) \ 558 do { \ 559 (DST)[0] = (SRCA)[0] * (SRCB)[0]; \ 560 (DST)[1] = (SRCA)[1] * (SRCB)[1]; \ 561 } while (0) 562 563 /** In-place addition */ 564 #define ACC_2V( DST, SRC ) \ 565 do { \ 566 (DST)[0] += (SRC)[0]; \ 567 (DST)[1] += (SRC)[1]; \ 568 } while (0) 569 570 /** Element-wise multiplication and addition */ 571 #define ACC_SCALE_2V( DST, SRCA, SRCB ) \ 572 do { \ 573 (DST)[0] += (SRCA)[0] * (SRCB)[0]; \ 574 (DST)[1] += (SRCA)[1] * (SRCB)[1]; \ 575 } while (0) 576 577 /** Scalar multiplication */ 578 #define SCALE_SCALAR_2V( DST, S, SRCB ) \ 579 do { \ 580 (DST)[0] = S * (SRCB)[0]; \ 581 (DST)[1] = S * (SRCB)[1]; \ 582 } while (0) 583 584 /** In-place scalar multiplication and addition */ 585 #define ACC_SCALE_SCALAR_2V( DST, S, SRCB ) \ 586 do { \ 587 (DST)[0] += S * (SRCB)[0]; \ 588 (DST)[1] += S * (SRCB)[1]; \ 589 } while (0) 590 591 /** In-place scalar multiplication */ 592 #define SELF_SCALE_SCALAR_2V( DST, S ) \ 593 do { \ 594 (DST)[0] *= S; \ 595 (DST)[1] *= S; \ 596 } while (0) 597 598 /** In-place scalar addition */ 599 #define ACC_SCALAR_2V( DST, S ) \ 600 do { \ 601 (DST)[0] += S; \ 602 (DST)[1] += S; \ 603 } while (0) 604 605 /** Assign scalers to short vectors */ 606 #define ASSIGN_2V( V, V0, V1 ) \ 607 do { \ 608 V[0] = V0; \ 609 V[1] = V1; \ 610 } while(0) 611 612 /*@}*/ 613 614 /** Copy \p sz elements into a homegeneous (4-element) vector, giving 615 * default values to the remaining components. 616 * The default values are chosen based on \p type. 617 */ 618 static inline void 619 COPY_CLEAN_4V_TYPE_AS_FLOAT(GLfloat dst[4], int sz, const GLfloat src[4], 620 GLenum type) 621 { 622 switch (type) { 623 case GL_FLOAT: 624 ASSIGN_4V(dst, 0, 0, 0, 1); 625 break; 626 case GL_INT: 627 ASSIGN_4V(dst, INT_AS_FLT(0), INT_AS_FLT(0), 628 INT_AS_FLT(0), INT_AS_FLT(1)); 629 break; 630 case GL_UNSIGNED_INT: 631 ASSIGN_4V(dst, UINT_AS_FLT(0), UINT_AS_FLT(0), 632 UINT_AS_FLT(0), UINT_AS_FLT(1)); 633 break; 634 default: 635 ASSIGN_4V(dst, 0.0f, 0.0f, 0.0f, 1.0f); /* silence warnings */ 636 ASSERT(!"Unexpected type in COPY_CLEAN_4V_TYPE_AS_FLOAT macro"); 637 } 638 COPY_SZ_4V(dst, sz, src); 639 } 640 641 /** \name Linear interpolation functions */ 642 /*@{*/ 643 644 static inline GLfloat 645 LINTERP(GLfloat t, GLfloat out, GLfloat in) 646 { 647 return out + t * (in - out); 648 } 649 650 static inline void 651 INTERP_3F(GLfloat t, GLfloat dst[3], const GLfloat out[3], const GLfloat in[3]) 652 { 653 dst[0] = LINTERP( t, out[0], in[0] ); 654 dst[1] = LINTERP( t, out[1], in[1] ); 655 dst[2] = LINTERP( t, out[2], in[2] ); 656 } 657 658 static inline void 659 INTERP_4F(GLfloat t, GLfloat dst[4], const GLfloat out[4], const GLfloat in[4]) 660 { 661 dst[0] = LINTERP( t, out[0], in[0] ); 662 dst[1] = LINTERP( t, out[1], in[1] ); 663 dst[2] = LINTERP( t, out[2], in[2] ); 664 dst[3] = LINTERP( t, out[3], in[3] ); 665 } 666 667 /*@}*/ 668 669 670 671 /** Clamp X to [MIN,MAX] */ 672 #define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) ) 673 674 /** Minimum of two values: */ 675 #define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) 676 677 /** Maximum of two values: */ 678 #define MAX2( A, B ) ( (A)>(B) ? (A) : (B) ) 679 680 /** Minimum and maximum of three values: */ 681 #define MIN3( A, B, C ) ((A) < (B) ? MIN2(A, C) : MIN2(B, C)) 682 #define MAX3( A, B, C ) ((A) > (B) ? MAX2(A, C) : MAX2(B, C)) 683 684 static inline unsigned 685 minify(unsigned value, unsigned levels) 686 { 687 return MAX2(1, value >> levels); 688 } 689 690 /** 691 * Return true if the given value is a power of two. 692 * 693 * Note that this considers 0 a power of two. 694 */ 695 static inline bool 696 is_power_of_two(unsigned value) 697 { 698 return (value & (value - 1)) == 0; 699 } 700 701 /** 702 * Align a value up to an alignment value 703 * 704 * If \c value is not already aligned to the requested alignment value, it 705 * will be rounded up. 706 * 707 * \param value Value to be rounded 708 * \param alignment Alignment value to be used. This must be a power of two. 709 * 710 * \sa ROUND_DOWN_TO() 711 */ 712 #define ALIGN(value, alignment) (((value) + (alignment) - 1) & ~((alignment) - 1)) 713 714 /** 715 * Align a value down to an alignment value 716 * 717 * If \c value is not already aligned to the requested alignment value, it 718 * will be rounded down. 719 * 720 * \param value Value to be rounded 721 * \param alignment Alignment value to be used. This must be a power of two. 722 * 723 * \sa ALIGN() 724 */ 725 #define ROUND_DOWN_TO(value, alignment) ((value) & ~(alignment - 1)) 726 727 728 /** Cross product of two 3-element vectors */ 729 static inline void 730 CROSS3(GLfloat n[3], const GLfloat u[3], const GLfloat v[3]) 731 { 732 n[0] = u[1] * v[2] - u[2] * v[1]; 733 n[1] = u[2] * v[0] - u[0] * v[2]; 734 n[2] = u[0] * v[1] - u[1] * v[0]; 735 } 736 737 738 /** Dot product of two 2-element vectors */ 739 static inline GLfloat 740 DOT2(const GLfloat a[2], const GLfloat b[2]) 741 { 742 return a[0] * b[0] + a[1] * b[1]; 743 } 744 745 static inline GLfloat 746 DOT3(const GLfloat a[3], const GLfloat b[3]) 747 { 748 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; 749 } 750 751 static inline GLfloat 752 DOT4(const GLfloat a[4], const GLfloat b[4]) 753 { 754 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; 755 } 756 757 758 static inline GLfloat 759 LEN_SQUARED_3FV(const GLfloat v[3]) 760 { 761 return DOT3(v, v); 762 } 763 764 static inline GLfloat 765 LEN_SQUARED_2FV(const GLfloat v[2]) 766 { 767 return DOT2(v, v); 768 } 769 770 771 static inline GLfloat 772 LEN_3FV(const GLfloat v[3]) 773 { 774 return sqrtf(LEN_SQUARED_3FV(v)); 775 } 776 777 static inline GLfloat 778 LEN_2FV(const GLfloat v[2]) 779 { 780 return sqrtf(LEN_SQUARED_2FV(v)); 781 } 782 783 784 /* Normalize a 3-element vector to unit length. */ 785 static inline void 786 NORMALIZE_3FV(GLfloat v[3]) 787 { 788 GLfloat len = (GLfloat) LEN_SQUARED_3FV(v); 789 if (len) { 790 len = INV_SQRTF(len); 791 v[0] *= len; 792 v[1] *= len; 793 v[2] *= len; 794 } 795 } 796 797 798 /** Test two floats have opposite signs */ 799 static inline GLboolean 800 DIFFERENT_SIGNS(GLfloat x, GLfloat y) 801 { 802 return signbit(x) != signbit(y); 803 } 804 805 806 /** Compute ceiling of integer quotient of A divided by B. */ 807 #define CEILING( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 ) 808 809 810 /** casts to silence warnings with some compilers */ 811 #define ENUM_TO_INT(E) ((GLint)(E)) 812 #define ENUM_TO_FLOAT(E) ((GLfloat)(GLint)(E)) 813 #define ENUM_TO_DOUBLE(E) ((GLdouble)(GLint)(E)) 814 #define ENUM_TO_BOOLEAN(E) ((E) ? GL_TRUE : GL_FALSE) 815 816 /* Compute the size of an array */ 817 #ifndef ARRAY_SIZE 818 # define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) 819 #endif 820 821 /* Stringify */ 822 #define STRINGIFY(x) #x 823 824 #endif 825