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 "util/macros.h" 35 #include "util/u_math.h" 36 #include "util/rounding.h" 37 #include "util/compiler.h" 38 #include "main/glheader.h" 39 #include "mesa_private.h" 40 41 42 /** 43 * \name Integer / float conversion for colors, normals, etc. 44 */ 45 /*@{*/ 46 47 /** Convert GLubyte in [0,255] to GLfloat in [0.0,1.0] */ 48 extern GLfloat _mesa_ubyte_to_float_color_tab[256]; 49 #define UBYTE_TO_FLOAT(u) _mesa_ubyte_to_float_color_tab[(unsigned int)(u)] 50 51 /** Convert GLfloat in [0.0,1.0] to GLubyte in [0,255] */ 52 #define FLOAT_TO_UBYTE(X) ((GLubyte) (GLint) ((X) * 255.0F)) 53 54 55 /** Convert GLbyte in [-128,127] to GLfloat in [-1.0,1.0] */ 56 #define BYTE_TO_FLOAT(B) ((2.0F * (B) + 1.0F) * (1.0F/255.0F)) 57 58 /** Convert GLfloat in [-1.0,1.0] to GLbyte in [-128,127] */ 59 #define FLOAT_TO_BYTE(X) ( (((GLint) (255.0F * (X))) - 1) / 2 ) 60 61 62 /** Convert GLbyte to GLfloat while preserving zero */ 63 #define BYTE_TO_FLOATZ(B) ((B) == 0 ? 0.0F : BYTE_TO_FLOAT(B)) 64 65 66 /** Convert GLbyte in [-128,127] to GLfloat in [-1.0,1.0], texture/fb data */ 67 #define BYTE_TO_FLOAT_TEX(B) ((B) == -128 ? -1.0F : (B) * (1.0F/127.0F)) 68 69 /** Convert GLfloat in [-1.0,1.0] to GLbyte in [-128,127], texture/fb data */ 70 #define FLOAT_TO_BYTE_TEX(X) CLAMP( (GLint) (127.0F * (X)), -128, 127 ) 71 72 /** Convert GLushort in [0,65535] to GLfloat in [0.0,1.0] */ 73 #define USHORT_TO_FLOAT(S) ((GLfloat) (S) * (1.0F / 65535.0F)) 74 75 /** Convert GLfloat in [0.0,1.0] to GLushort in [0, 65535] */ 76 #define FLOAT_TO_USHORT(X) ((GLuint) ((X) * 65535.0F)) 77 78 79 /** Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0] */ 80 #define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F)) 81 82 /** Convert GLfloat in [-1.0,1.0] to GLshort in [-32768,32767] */ 83 #define FLOAT_TO_SHORT(X) ( (((GLint) (65535.0F * (X))) - 1) / 2 ) 84 85 /** Convert GLshort to GLfloat while preserving zero */ 86 #define SHORT_TO_FLOATZ(S) ((S) == 0 ? 0.0F : SHORT_TO_FLOAT(S)) 87 88 89 /** Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0], texture/fb data */ 90 #define SHORT_TO_FLOAT_TEX(S) ((S) == -32768 ? -1.0F : (S) * (1.0F/32767.0F)) 91 92 /** Convert GLfloat in [-1.0,1.0] to GLshort in [-32768,32767], texture/fb data */ 93 #define FLOAT_TO_SHORT_TEX(X) ( (GLint) (32767.0F * (X)) ) 94 95 96 /** Convert GLuint in [0,4294967295] to GLfloat in [0.0,1.0] */ 97 #define UINT_TO_FLOAT(U) ((GLfloat) ((U) * (1.0F / 4294967295.0))) 98 99 /** Convert GLfloat in [0.0,1.0] to GLuint in [0,4294967295] */ 100 #define FLOAT_TO_UINT(X) ((GLuint) ((X) * 4294967295.0)) 101 102 103 /** Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0] */ 104 #define INT_TO_FLOAT(I) ((GLfloat) ((2.0F * (I) + 1.0F) * (1.0F/4294967294.0))) 105 106 /** Convert GLfloat in [-1.0,1.0] to GLint in [-2147483648,2147483647] */ 107 /* causes overflow: 108 #define FLOAT_TO_INT(X) ( (((GLint) (4294967294.0 * (X))) - 1) / 2 ) 109 */ 110 /* a close approximation: */ 111 #define FLOAT_TO_INT(X) ( (GLint) (2147483647.0 * (X)) ) 112 113 /** Convert GLfloat in [-1.0,1.0] to GLint64 in [-(1<<63),(1 << 63) -1] */ 114 #define FLOAT_TO_INT64(X) ( (GLint64) (9223372036854775807.0 * (double)(X)) ) 115 116 117 /** Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0], texture/fb data */ 118 #define INT_TO_FLOAT_TEX(I) ((I) == -2147483648 ? -1.0F : (I) * (1.0F/2147483647.0)) 119 120 /** Convert GLfloat in [-1.0,1.0] to GLint in [-2147483648,2147483647], texture/fb data */ 121 #define FLOAT_TO_INT_TEX(X) ( (GLint) (2147483647.0 * (X)) ) 122 123 124 #define BYTE_TO_UBYTE(b) ((GLubyte) ((b) < 0 ? 0 : (GLubyte) (b))) 125 #define SHORT_TO_UBYTE(s) ((GLubyte) ((s) < 0 ? 0 : (GLubyte) ((s) >> 7))) 126 #define USHORT_TO_UBYTE(s) ((GLubyte) ((s) >> 8)) 127 #define INT_TO_UBYTE(i) ((GLubyte) ((i) < 0 ? 0 : (GLubyte) ((i) >> 23))) 128 #define UINT_TO_UBYTE(i) ((GLubyte) ((i) >> 24)) 129 130 131 #define BYTE_TO_USHORT(b) ((b) < 0 ? 0 : ((GLushort) (((b) * 65535) / 255))) 132 #define UBYTE_TO_USHORT(b) (((GLushort) (b) << 8) | (GLushort) (b)) 133 #define SHORT_TO_USHORT(s) ((s) < 0 ? 0 : ((GLushort) (((s) * 65535 / 32767)))) 134 #define INT_TO_USHORT(i) ((i) < 0 ? 0 : ((GLushort) ((i) >> 15))) 135 #define UINT_TO_USHORT(i) ((i) < 0 ? 0 : ((GLushort) ((i) >> 16))) 136 #define UNCLAMPED_FLOAT_TO_USHORT(us, f) \ 137 us = ( (GLushort) _mesa_lroundevenf( CLAMP((f), 0.0F, 1.0F) * 65535.0F) ) 138 #define CLAMPED_FLOAT_TO_USHORT(us, f) \ 139 us = ( (GLushort) _mesa_lroundevenf( (f) * 65535.0F) ) 140 141 #define UNCLAMPED_FLOAT_TO_SHORT(s, f) \ 142 s = ( (GLshort) _mesa_lroundevenf( CLAMP((f), -1.0F, 1.0F) * 32767.0F) ) 143 144 /*** 145 *** UNCLAMPED_FLOAT_TO_UBYTE: clamp float to [0,1] and map to ubyte in [0,255] 146 *** CLAMPED_FLOAT_TO_UBYTE: map float known to be in [0,1] to ubyte in [0,255] 147 ***/ 148 #ifndef DEBUG 149 /* This function/macro is sensitive to precision. Test very carefully 150 * if you change it! 151 */ 152 #define UNCLAMPED_FLOAT_TO_UBYTE(UB, FLT) \ 153 do { \ 154 fi_type __tmp; \ 155 __tmp.f = (FLT); \ 156 if (__tmp.i < 0) \ 157 UB = (GLubyte) 0; \ 158 else if (__tmp.i >= IEEE_ONE) \ 159 UB = (GLubyte) 255; \ 160 else { \ 161 __tmp.f = __tmp.f * (255.0F/256.0F) + 32768.0F; \ 162 UB = (GLubyte) __tmp.i; \ 163 } \ 164 } while (0) 165 #define CLAMPED_FLOAT_TO_UBYTE(UB, FLT) \ 166 do { \ 167 fi_type __tmp; \ 168 __tmp.f = (FLT) * (255.0F/256.0F) + 32768.0F; \ 169 UB = (GLubyte) __tmp.i; \ 170 } while (0) 171 #else 172 #define UNCLAMPED_FLOAT_TO_UBYTE(ub, f) \ 173 ub = ((GLubyte) _mesa_lroundevenf(CLAMP((f), 0.0F, 1.0F) * 255.0F)) 174 #define CLAMPED_FLOAT_TO_UBYTE(ub, f) \ 175 ub = ((GLubyte) _mesa_lroundevenf((f) * 255.0F)) 176 #endif 177 178 static fi_type UINT_AS_UNION(GLuint u) 179 { 180 fi_type tmp; 181 tmp.u = u; 182 return tmp; 183 } 184 185 static inline fi_type INT_AS_UNION(GLint i) 186 { 187 fi_type tmp; 188 tmp.i = i; 189 return tmp; 190 } 191 192 static inline fi_type FLOAT_AS_UNION(GLfloat f) 193 { 194 fi_type tmp; 195 tmp.f = f; 196 return tmp; 197 } 198 199 static inline uint64_t DOUBLE_AS_UINT64(double d) 200 { 201 union { 202 double d; 203 uint64_t u64; 204 } tmp; 205 tmp.d = d; 206 return tmp.u64; 207 } 208 209 static inline double UINT64_AS_DOUBLE(uint64_t u) 210 { 211 union { 212 double d; 213 uint64_t u64; 214 } tmp; 215 tmp.u64 = u; 216 return tmp.d; 217 } 218 219 /* First sign-extend x, then return uint32_t. */ 220 #define INT_AS_UINT(x) ((uint32_t)((int32_t)(x))) 221 #define FLOAT_AS_UINT(x) (FLOAT_AS_UNION(x).u) 222 223 /** 224 * Convert a floating point value to an unsigned fixed point value. 225 * 226 * \param frac_bits The number of bits used to store the fractional part. 227 */ 228 static inline uint32_t 229 U_FIXED(float value, uint32_t frac_bits) 230 { 231 value *= (1 << frac_bits); 232 return value < 0.0f ? 0 : (uint32_t) value; 233 } 234 235 /** 236 * Convert a floating point value to an signed fixed point value. 237 * 238 * \param frac_bits The number of bits used to store the fractional part. 239 */ 240 static inline int32_t 241 S_FIXED(float value, uint32_t frac_bits) 242 { 243 return (int32_t) (value * (1 << frac_bits)); 244 } 245 /*@}*/ 246 247 248 /** Stepping a GLfloat pointer by a byte stride */ 249 #define STRIDE_F(p, i) (p = (GLfloat *)((GLubyte *)p + i)) 250 /** Stepping a GLuint pointer by a byte stride */ 251 #define STRIDE_UI(p, i) (p = (GLuint *)((GLubyte *)p + i)) 252 /** Stepping a GLubyte[4] pointer by a byte stride */ 253 #define STRIDE_4UB(p, i) (p = (GLubyte (*)[4])((GLubyte *)p + i)) 254 /** Stepping a GLfloat[4] pointer by a byte stride */ 255 #define STRIDE_4F(p, i) (p = (GLfloat (*)[4])((GLubyte *)p + i)) 256 /** Stepping a \p t pointer by a byte stride */ 257 #define STRIDE_T(p, t, i) (p = (t)((GLubyte *)p + i)) 258 259 260 /**********************************************************************/ 261 /** \name 4-element vector operations */ 262 /*@{*/ 263 264 /** Zero */ 265 #define ZERO_4V( DST ) (DST)[0] = (DST)[1] = (DST)[2] = (DST)[3] = 0 266 267 /** Test for equality */ 268 #define TEST_EQ_4V(a,b) ((a)[0] == (b)[0] && \ 269 (a)[1] == (b)[1] && \ 270 (a)[2] == (b)[2] && \ 271 (a)[3] == (b)[3]) 272 273 /** Test for equality (unsigned bytes) */ 274 static inline GLboolean 275 TEST_EQ_4UBV(const GLubyte a[4], const GLubyte b[4]) 276 { 277 #if defined(__i386__) 278 return *((const GLuint *) a) == *((const GLuint *) b); 279 #else 280 return TEST_EQ_4V(a, b); 281 #endif 282 } 283 284 285 /** Copy a 4-element vector */ 286 #define COPY_4V( DST, SRC ) \ 287 do { \ 288 (DST)[0] = (SRC)[0]; \ 289 (DST)[1] = (SRC)[1]; \ 290 (DST)[2] = (SRC)[2]; \ 291 (DST)[3] = (SRC)[3]; \ 292 } while (0) 293 294 /** Copy a 4-element unsigned byte vector */ 295 static inline void 296 COPY_4UBV(GLubyte dst[4], const GLubyte src[4]) 297 { 298 #if defined(__i386__) 299 *((GLuint *) dst) = *((GLuint *) src); 300 #else 301 /* The GLuint cast might fail if DST or SRC are not dword-aligned (RISC) */ 302 COPY_4V(dst, src); 303 #endif 304 } 305 306 /** Copy \p SZ elements into a 4-element vector */ 307 #define COPY_SZ_4V(DST, SZ, SRC) \ 308 do { \ 309 switch (SZ) { \ 310 case 4: (DST)[3] = (SRC)[3]; \ 311 case 3: (DST)[2] = (SRC)[2]; \ 312 case 2: (DST)[1] = (SRC)[1]; \ 313 case 1: (DST)[0] = (SRC)[0]; \ 314 } \ 315 } while(0) 316 317 /** Copy \p SZ elements into a homegeneous (4-element) vector, giving 318 * default values to the remaining */ 319 #define COPY_CLEAN_4V(DST, SZ, SRC) \ 320 do { \ 321 ASSIGN_4V( DST, 0, 0, 0, 1 ); \ 322 COPY_SZ_4V( DST, SZ, SRC ); \ 323 } while (0) 324 325 /** Subtraction */ 326 #define SUB_4V( DST, SRCA, SRCB ) \ 327 do { \ 328 (DST)[0] = (SRCA)[0] - (SRCB)[0]; \ 329 (DST)[1] = (SRCA)[1] - (SRCB)[1]; \ 330 (DST)[2] = (SRCA)[2] - (SRCB)[2]; \ 331 (DST)[3] = (SRCA)[3] - (SRCB)[3]; \ 332 } while (0) 333 334 /** Addition */ 335 #define ADD_4V( DST, SRCA, SRCB ) \ 336 do { \ 337 (DST)[0] = (SRCA)[0] + (SRCB)[0]; \ 338 (DST)[1] = (SRCA)[1] + (SRCB)[1]; \ 339 (DST)[2] = (SRCA)[2] + (SRCB)[2]; \ 340 (DST)[3] = (SRCA)[3] + (SRCB)[3]; \ 341 } while (0) 342 343 /** Element-wise multiplication */ 344 #define SCALE_4V( DST, SRCA, SRCB ) \ 345 do { \ 346 (DST)[0] = (SRCA)[0] * (SRCB)[0]; \ 347 (DST)[1] = (SRCA)[1] * (SRCB)[1]; \ 348 (DST)[2] = (SRCA)[2] * (SRCB)[2]; \ 349 (DST)[3] = (SRCA)[3] * (SRCB)[3]; \ 350 } while (0) 351 352 /** In-place addition */ 353 #define ACC_4V( DST, SRC ) \ 354 do { \ 355 (DST)[0] += (SRC)[0]; \ 356 (DST)[1] += (SRC)[1]; \ 357 (DST)[2] += (SRC)[2]; \ 358 (DST)[3] += (SRC)[3]; \ 359 } while (0) 360 361 /** Element-wise multiplication and addition */ 362 #define ACC_SCALE_4V( DST, SRCA, SRCB ) \ 363 do { \ 364 (DST)[0] += (SRCA)[0] * (SRCB)[0]; \ 365 (DST)[1] += (SRCA)[1] * (SRCB)[1]; \ 366 (DST)[2] += (SRCA)[2] * (SRCB)[2]; \ 367 (DST)[3] += (SRCA)[3] * (SRCB)[3]; \ 368 } while (0) 369 370 /** In-place scalar multiplication and addition */ 371 #define ACC_SCALE_SCALAR_4V( DST, S, SRCB ) \ 372 do { \ 373 (DST)[0] += S * (SRCB)[0]; \ 374 (DST)[1] += S * (SRCB)[1]; \ 375 (DST)[2] += S * (SRCB)[2]; \ 376 (DST)[3] += S * (SRCB)[3]; \ 377 } while (0) 378 379 /** Scalar multiplication */ 380 #define SCALE_SCALAR_4V( DST, S, SRCB ) \ 381 do { \ 382 (DST)[0] = S * (SRCB)[0]; \ 383 (DST)[1] = S * (SRCB)[1]; \ 384 (DST)[2] = S * (SRCB)[2]; \ 385 (DST)[3] = S * (SRCB)[3]; \ 386 } while (0) 387 388 /** In-place scalar multiplication */ 389 #define SELF_SCALE_SCALAR_4V( DST, S ) \ 390 do { \ 391 (DST)[0] *= S; \ 392 (DST)[1] *= S; \ 393 (DST)[2] *= S; \ 394 (DST)[3] *= S; \ 395 } while (0) 396 397 /*@}*/ 398 399 400 /**********************************************************************/ 401 /** \name 3-element vector operations*/ 402 /*@{*/ 403 404 /** Zero */ 405 #define ZERO_3V( DST ) (DST)[0] = (DST)[1] = (DST)[2] = 0 406 407 /** Test for equality */ 408 #define TEST_EQ_3V(a,b) \ 409 ((a)[0] == (b)[0] && \ 410 (a)[1] == (b)[1] && \ 411 (a)[2] == (b)[2]) 412 413 /** Copy a 3-element vector */ 414 #define COPY_3V( DST, SRC ) \ 415 do { \ 416 (DST)[0] = (SRC)[0]; \ 417 (DST)[1] = (SRC)[1]; \ 418 (DST)[2] = (SRC)[2]; \ 419 } while (0) 420 421 /** Copy a 3-element vector with cast */ 422 #define COPY_3V_CAST( DST, SRC, CAST ) \ 423 do { \ 424 (DST)[0] = (CAST)(SRC)[0]; \ 425 (DST)[1] = (CAST)(SRC)[1]; \ 426 (DST)[2] = (CAST)(SRC)[2]; \ 427 } while (0) 428 429 /** Copy a 3-element float vector */ 430 #define COPY_3FV( DST, SRC ) \ 431 do { \ 432 const GLfloat *_tmp = (SRC); \ 433 (DST)[0] = _tmp[0]; \ 434 (DST)[1] = _tmp[1]; \ 435 (DST)[2] = _tmp[2]; \ 436 } while (0) 437 438 /** Subtraction */ 439 #define SUB_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 /** Addition */ 447 #define ADD_3V( DST, SRCA, SRCB ) \ 448 do { \ 449 (DST)[0] = (SRCA)[0] + (SRCB)[0]; \ 450 (DST)[1] = (SRCA)[1] + (SRCB)[1]; \ 451 (DST)[2] = (SRCA)[2] + (SRCB)[2]; \ 452 } while (0) 453 454 /** In-place scalar multiplication */ 455 #define SCALE_3V( DST, SRCA, SRCB ) \ 456 do { \ 457 (DST)[0] = (SRCA)[0] * (SRCB)[0]; \ 458 (DST)[1] = (SRCA)[1] * (SRCB)[1]; \ 459 (DST)[2] = (SRCA)[2] * (SRCB)[2]; \ 460 } while (0) 461 462 /** In-place element-wise multiplication */ 463 #define SELF_SCALE_3V( DST, SRC ) \ 464 do { \ 465 (DST)[0] *= (SRC)[0]; \ 466 (DST)[1] *= (SRC)[1]; \ 467 (DST)[2] *= (SRC)[2]; \ 468 } while (0) 469 470 /** In-place addition */ 471 #define ACC_3V( DST, SRC ) \ 472 do { \ 473 (DST)[0] += (SRC)[0]; \ 474 (DST)[1] += (SRC)[1]; \ 475 (DST)[2] += (SRC)[2]; \ 476 } while (0) 477 478 /** Element-wise multiplication and addition */ 479 #define ACC_SCALE_3V( DST, SRCA, SRCB ) \ 480 do { \ 481 (DST)[0] += (SRCA)[0] * (SRCB)[0]; \ 482 (DST)[1] += (SRCA)[1] * (SRCB)[1]; \ 483 (DST)[2] += (SRCA)[2] * (SRCB)[2]; \ 484 } while (0) 485 486 /** Scalar multiplication */ 487 #define SCALE_SCALAR_3V( DST, S, SRCB ) \ 488 do { \ 489 (DST)[0] = S * (SRCB)[0]; \ 490 (DST)[1] = S * (SRCB)[1]; \ 491 (DST)[2] = S * (SRCB)[2]; \ 492 } while (0) 493 494 /** In-place scalar multiplication and addition */ 495 #define ACC_SCALE_SCALAR_3V( DST, S, SRCB ) \ 496 do { \ 497 (DST)[0] += S * (SRCB)[0]; \ 498 (DST)[1] += S * (SRCB)[1]; \ 499 (DST)[2] += S * (SRCB)[2]; \ 500 } while (0) 501 502 /** In-place scalar multiplication */ 503 #define SELF_SCALE_SCALAR_3V( DST, S ) \ 504 do { \ 505 (DST)[0] *= S; \ 506 (DST)[1] *= S; \ 507 (DST)[2] *= S; \ 508 } while (0) 509 510 /** In-place scalar addition */ 511 #define ACC_SCALAR_3V( DST, S ) \ 512 do { \ 513 (DST)[0] += S; \ 514 (DST)[1] += S; \ 515 (DST)[2] += S; \ 516 } while (0) 517 518 /** Assignment */ 519 #define ASSIGN_3V( V, V0, V1, V2 ) \ 520 do { \ 521 V[0] = V0; \ 522 V[1] = V1; \ 523 V[2] = V2; \ 524 } while(0) 525 526 /*@}*/ 527 528 529 /**********************************************************************/ 530 /** \name 2-element vector operations*/ 531 /*@{*/ 532 533 /** Zero */ 534 #define ZERO_2V( DST ) (DST)[0] = (DST)[1] = 0 535 536 /** Copy a 2-element vector */ 537 #define COPY_2V( DST, SRC ) \ 538 do { \ 539 (DST)[0] = (SRC)[0]; \ 540 (DST)[1] = (SRC)[1]; \ 541 } while (0) 542 543 /** Copy a 2-element vector with cast */ 544 #define COPY_2V_CAST( DST, SRC, CAST ) \ 545 do { \ 546 (DST)[0] = (CAST)(SRC)[0]; \ 547 (DST)[1] = (CAST)(SRC)[1]; \ 548 } while (0) 549 550 /** Copy a 2-element float vector */ 551 #define COPY_2FV( DST, SRC ) \ 552 do { \ 553 const GLfloat *_tmp = (SRC); \ 554 (DST)[0] = _tmp[0]; \ 555 (DST)[1] = _tmp[1]; \ 556 } while (0) 557 558 /** Subtraction */ 559 #define SUB_2V( DST, SRCA, SRCB ) \ 560 do { \ 561 (DST)[0] = (SRCA)[0] - (SRCB)[0]; \ 562 (DST)[1] = (SRCA)[1] - (SRCB)[1]; \ 563 } while (0) 564 565 /** Addition */ 566 #define ADD_2V( DST, SRCA, SRCB ) \ 567 do { \ 568 (DST)[0] = (SRCA)[0] + (SRCB)[0]; \ 569 (DST)[1] = (SRCA)[1] + (SRCB)[1]; \ 570 } while (0) 571 572 /** In-place scalar multiplication */ 573 #define SCALE_2V( DST, SRCA, SRCB ) \ 574 do { \ 575 (DST)[0] = (SRCA)[0] * (SRCB)[0]; \ 576 (DST)[1] = (SRCA)[1] * (SRCB)[1]; \ 577 } while (0) 578 579 /** In-place addition */ 580 #define ACC_2V( DST, SRC ) \ 581 do { \ 582 (DST)[0] += (SRC)[0]; \ 583 (DST)[1] += (SRC)[1]; \ 584 } while (0) 585 586 /** Element-wise multiplication and addition */ 587 #define ACC_SCALE_2V( DST, SRCA, SRCB ) \ 588 do { \ 589 (DST)[0] += (SRCA)[0] * (SRCB)[0]; \ 590 (DST)[1] += (SRCA)[1] * (SRCB)[1]; \ 591 } while (0) 592 593 /** Scalar multiplication */ 594 #define SCALE_SCALAR_2V( DST, S, SRCB ) \ 595 do { \ 596 (DST)[0] = S * (SRCB)[0]; \ 597 (DST)[1] = S * (SRCB)[1]; \ 598 } while (0) 599 600 /** In-place scalar multiplication and addition */ 601 #define ACC_SCALE_SCALAR_2V( DST, S, SRCB ) \ 602 do { \ 603 (DST)[0] += S * (SRCB)[0]; \ 604 (DST)[1] += S * (SRCB)[1]; \ 605 } while (0) 606 607 /** In-place scalar multiplication */ 608 #define SELF_SCALE_SCALAR_2V( DST, S ) \ 609 do { \ 610 (DST)[0] *= S; \ 611 (DST)[1] *= S; \ 612 } while (0) 613 614 /** In-place scalar addition */ 615 #define ACC_SCALAR_2V( DST, S ) \ 616 do { \ 617 (DST)[0] += S; \ 618 (DST)[1] += S; \ 619 } while (0) 620 621 /** Assign scalers to short vectors */ 622 #define ASSIGN_2V( V, V0, V1 ) \ 623 do { \ 624 V[0] = V0; \ 625 V[1] = V1; \ 626 } while(0) 627 628 /*@}*/ 629 630 /** Copy \p sz elements into a homegeneous (4-element) vector, giving 631 * default values to the remaining components. 632 * The default values are chosen based on \p type. 633 */ 634 static inline void 635 COPY_CLEAN_4V_TYPE_AS_UNION(fi_type dst[4], int sz, const fi_type src[4], 636 GLenum type) 637 { 638 switch (type) { 639 case GL_FLOAT: 640 ASSIGN_4V(dst, FLOAT_AS_UNION(0), FLOAT_AS_UNION(0), 641 FLOAT_AS_UNION(0), FLOAT_AS_UNION(1)); 642 break; 643 case GL_INT: 644 ASSIGN_4V(dst, INT_AS_UNION(0), INT_AS_UNION(0), 645 INT_AS_UNION(0), INT_AS_UNION(1)); 646 break; 647 case GL_UNSIGNED_INT: 648 ASSIGN_4V(dst, UINT_AS_UNION(0), UINT_AS_UNION(0), 649 UINT_AS_UNION(0), UINT_AS_UNION(1)); 650 break; 651 default: 652 ASSIGN_4V(dst, FLOAT_AS_UNION(0), FLOAT_AS_UNION(0), 653 FLOAT_AS_UNION(0), FLOAT_AS_UNION(1)); /* silence warnings */ 654 assert(!"Unexpected type in COPY_CLEAN_4V_TYPE_AS_UNION macro"); 655 } 656 COPY_SZ_4V(dst, sz, src); 657 } 658 659 /** \name Linear interpolation functions */ 660 /*@{*/ 661 662 static inline GLfloat 663 LINTERP(GLfloat t, GLfloat out, GLfloat in) 664 { 665 return out + t * (in - out); 666 } 667 668 static inline void 669 INTERP_3F(GLfloat t, GLfloat dst[3], const GLfloat out[3], const GLfloat in[3]) 670 { 671 dst[0] = LINTERP( t, out[0], in[0] ); 672 dst[1] = LINTERP( t, out[1], in[1] ); 673 dst[2] = LINTERP( t, out[2], in[2] ); 674 } 675 676 static inline void 677 INTERP_4F(GLfloat t, GLfloat dst[4], const GLfloat out[4], const GLfloat in[4]) 678 { 679 dst[0] = LINTERP( t, out[0], in[0] ); 680 dst[1] = LINTERP( t, out[1], in[1] ); 681 dst[2] = LINTERP( t, out[2], in[2] ); 682 dst[3] = LINTERP( t, out[3], in[3] ); 683 } 684 685 /*@}*/ 686 687 688 689 static inline unsigned 690 minify(unsigned value, unsigned levels) 691 { 692 return MAX2(1, value >> levels); 693 } 694 695 696 /** Cross product of two 3-element vectors */ 697 static inline void 698 CROSS3(GLfloat n[3], const GLfloat u[3], const GLfloat v[3]) 699 { 700 n[0] = u[1] * v[2] - u[2] * v[1]; 701 n[1] = u[2] * v[0] - u[0] * v[2]; 702 n[2] = u[0] * v[1] - u[1] * v[0]; 703 } 704 705 706 /** Dot product of two 2-element vectors */ 707 static inline GLfloat 708 DOT2(const GLfloat a[2], const GLfloat b[2]) 709 { 710 return a[0] * b[0] + a[1] * b[1]; 711 } 712 713 static inline GLfloat 714 DOT3(const GLfloat a[3], const GLfloat b[3]) 715 { 716 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; 717 } 718 719 static inline GLfloat 720 DOT4(const GLfloat a[4], const GLfloat b[4]) 721 { 722 return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; 723 } 724 725 726 static inline GLfloat 727 LEN_SQUARED_3FV(const GLfloat v[3]) 728 { 729 return DOT3(v, v); 730 } 731 732 static inline GLfloat 733 LEN_SQUARED_2FV(const GLfloat v[2]) 734 { 735 return DOT2(v, v); 736 } 737 738 739 static inline GLfloat 740 LEN_3FV(const GLfloat v[3]) 741 { 742 return sqrtf(LEN_SQUARED_3FV(v)); 743 } 744 745 static inline GLfloat 746 LEN_2FV(const GLfloat v[2]) 747 { 748 return sqrtf(LEN_SQUARED_2FV(v)); 749 } 750 751 752 /* Normalize a 3-element vector to unit length. */ 753 static inline void 754 NORMALIZE_3FV(GLfloat v[3]) 755 { 756 GLfloat len = (GLfloat) LEN_SQUARED_3FV(v); 757 if (len) { 758 len = 1.0f / sqrtf(len); 759 v[0] *= len; 760 v[1] *= len; 761 v[2] *= len; 762 } 763 } 764 765 766 /** Test two floats have opposite signs */ 767 static inline GLboolean 768 DIFFERENT_SIGNS(GLfloat x, GLfloat y) 769 { 770 #ifdef _MSC_VER 771 #pragma warning( push ) 772 #pragma warning( disable : 6334 ) /* sizeof operator applied to an expression with an operator may yield unexpected results */ 773 #endif 774 return signbit(x) != signbit(y); 775 #ifdef _MSC_VER 776 #pragma warning( pop ) 777 #endif 778 } 779 780 781 /** casts to silence warnings with some compilers */ 782 #define ENUM_TO_INT(E) ((GLint)(E)) 783 #define ENUM_TO_FLOAT(E) ((GLfloat)(GLint)(E)) 784 #define ENUM_TO_DOUBLE(E) ((GLdouble)(GLint)(E)) 785 #define ENUM_TO_BOOLEAN(E) ((E) ? GL_TRUE : GL_FALSE) 786 787 788 /* Stringify */ 789 #define STRINGIFY(x) #x 790 791 /* 792 * For GL_ARB_vertex_buffer_object we need to treat vertex array pointers 793 * as offsets into buffer stores. Since the vertex array pointer and 794 * buffer store pointer are both pointers and we need to add them, we use 795 * this macro. 796 * Both pointers/offsets are expressed in bytes. 797 */ 798 #define ADD_POINTERS(A, B) ( (GLubyte *) (A) + (uintptr_t) (B) ) 799 800 #endif 801