macros.h revision 4a49301e
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] */ 43extern 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) ((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/*@}*/ 131 132 133/** Stepping a GLfloat pointer by a byte stride */ 134#define STRIDE_F(p, i) (p = (GLfloat *)((GLubyte *)p + i)) 135/** Stepping a GLuint pointer by a byte stride */ 136#define STRIDE_UI(p, i) (p = (GLuint *)((GLubyte *)p + i)) 137/** Stepping a GLubyte[4] pointer by a byte stride */ 138#define STRIDE_4UB(p, i) (p = (GLubyte (*)[4])((GLubyte *)p + i)) 139/** Stepping a GLfloat[4] pointer by a byte stride */ 140#define STRIDE_4F(p, i) (p = (GLfloat (*)[4])((GLubyte *)p + i)) 141/** Stepping a GLchan[4] pointer by a byte stride */ 142#define STRIDE_4CHAN(p, i) (p = (GLchan (*)[4])((GLubyte *)p + i)) 143/** Stepping a GLchan pointer by a byte stride */ 144#define STRIDE_CHAN(p, i) (p = (GLchan *)((GLubyte *)p + i)) 145/** Stepping a \p t pointer by a byte stride */ 146#define STRIDE_T(p, t, i) (p = (t)((GLubyte *)p + i)) 147 148 149/**********************************************************************/ 150/** \name 4-element vector operations */ 151/*@{*/ 152 153/** Zero */ 154#define ZERO_4V( DST ) (DST)[0] = (DST)[1] = (DST)[2] = (DST)[3] = 0 155 156/** Test for equality */ 157#define TEST_EQ_4V(a,b) ((a)[0] == (b)[0] && \ 158 (a)[1] == (b)[1] && \ 159 (a)[2] == (b)[2] && \ 160 (a)[3] == (b)[3]) 161 162/** Test for equality (unsigned bytes) */ 163#if defined(__i386__) 164#define TEST_EQ_4UBV(DST, SRC) *((GLuint*)(DST)) == *((GLuint*)(SRC)) 165#else 166#define TEST_EQ_4UBV(DST, SRC) TEST_EQ_4V(DST, SRC) 167#endif 168 169/** Copy a 4-element vector */ 170#define COPY_4V( DST, SRC ) \ 171do { \ 172 (DST)[0] = (SRC)[0]; \ 173 (DST)[1] = (SRC)[1]; \ 174 (DST)[2] = (SRC)[2]; \ 175 (DST)[3] = (SRC)[3]; \ 176} while (0) 177 178/** Copy a 4-element vector with cast */ 179#define COPY_4V_CAST( DST, SRC, CAST ) \ 180do { \ 181 (DST)[0] = (CAST)(SRC)[0]; \ 182 (DST)[1] = (CAST)(SRC)[1]; \ 183 (DST)[2] = (CAST)(SRC)[2]; \ 184 (DST)[3] = (CAST)(SRC)[3]; \ 185} while (0) 186 187/** Copy a 4-element unsigned byte vector */ 188#if defined(__i386__) 189#define COPY_4UBV(DST, SRC) \ 190do { \ 191 *((GLuint*)(DST)) = *((GLuint*)(SRC)); \ 192} while (0) 193#else 194/* The GLuint cast might fail if DST or SRC are not dword-aligned (RISC) */ 195#define COPY_4UBV(DST, SRC) \ 196do { \ 197 (DST)[0] = (SRC)[0]; \ 198 (DST)[1] = (SRC)[1]; \ 199 (DST)[2] = (SRC)[2]; \ 200 (DST)[3] = (SRC)[3]; \ 201} while (0) 202#endif 203 204/** 205 * Copy a 4-element float vector (avoid using FPU registers) 206 * XXX Could use two 64-bit moves on 64-bit systems 207 */ 208#define COPY_4FV( DST, SRC ) \ 209do { \ 210 const GLuint *_s = (const GLuint *) (SRC); \ 211 GLuint *_d = (GLuint *) (DST); \ 212 _d[0] = _s[0]; \ 213 _d[1] = _s[1]; \ 214 _d[2] = _s[2]; \ 215 _d[3] = _s[3]; \ 216} while (0) 217 218/** Copy \p SZ elements into a 4-element vector */ 219#define COPY_SZ_4V(DST, SZ, SRC) \ 220do { \ 221 switch (SZ) { \ 222 case 4: (DST)[3] = (SRC)[3]; \ 223 case 3: (DST)[2] = (SRC)[2]; \ 224 case 2: (DST)[1] = (SRC)[1]; \ 225 case 1: (DST)[0] = (SRC)[0]; \ 226 } \ 227} while(0) 228 229/** Copy \p SZ elements into a homegeneous (4-element) vector, giving 230 * default values to the remaining */ 231#define COPY_CLEAN_4V(DST, SZ, SRC) \ 232do { \ 233 ASSIGN_4V( DST, 0, 0, 0, 1 ); \ 234 COPY_SZ_4V( DST, SZ, SRC ); \ 235} while (0) 236 237/** Subtraction */ 238#define SUB_4V( DST, SRCA, SRCB ) \ 239do { \ 240 (DST)[0] = (SRCA)[0] - (SRCB)[0]; \ 241 (DST)[1] = (SRCA)[1] - (SRCB)[1]; \ 242 (DST)[2] = (SRCA)[2] - (SRCB)[2]; \ 243 (DST)[3] = (SRCA)[3] - (SRCB)[3]; \ 244} while (0) 245 246/** Addition */ 247#define ADD_4V( DST, SRCA, SRCB ) \ 248do { \ 249 (DST)[0] = (SRCA)[0] + (SRCB)[0]; \ 250 (DST)[1] = (SRCA)[1] + (SRCB)[1]; \ 251 (DST)[2] = (SRCA)[2] + (SRCB)[2]; \ 252 (DST)[3] = (SRCA)[3] + (SRCB)[3]; \ 253} while (0) 254 255/** Element-wise multiplication */ 256#define SCALE_4V( DST, SRCA, SRCB ) \ 257do { \ 258 (DST)[0] = (SRCA)[0] * (SRCB)[0]; \ 259 (DST)[1] = (SRCA)[1] * (SRCB)[1]; \ 260 (DST)[2] = (SRCA)[2] * (SRCB)[2]; \ 261 (DST)[3] = (SRCA)[3] * (SRCB)[3]; \ 262} while (0) 263 264/** In-place addition */ 265#define ACC_4V( DST, SRC ) \ 266do { \ 267 (DST)[0] += (SRC)[0]; \ 268 (DST)[1] += (SRC)[1]; \ 269 (DST)[2] += (SRC)[2]; \ 270 (DST)[3] += (SRC)[3]; \ 271} while (0) 272 273/** Element-wise multiplication and addition */ 274#define ACC_SCALE_4V( DST, SRCA, SRCB ) \ 275do { \ 276 (DST)[0] += (SRCA)[0] * (SRCB)[0]; \ 277 (DST)[1] += (SRCA)[1] * (SRCB)[1]; \ 278 (DST)[2] += (SRCA)[2] * (SRCB)[2]; \ 279 (DST)[3] += (SRCA)[3] * (SRCB)[3]; \ 280} while (0) 281 282/** In-place scalar multiplication and addition */ 283#define ACC_SCALE_SCALAR_4V( DST, S, SRCB ) \ 284do { \ 285 (DST)[0] += S * (SRCB)[0]; \ 286 (DST)[1] += S * (SRCB)[1]; \ 287 (DST)[2] += S * (SRCB)[2]; \ 288 (DST)[3] += S * (SRCB)[3]; \ 289} while (0) 290 291/** Scalar multiplication */ 292#define SCALE_SCALAR_4V( DST, S, SRCB ) \ 293do { \ 294 (DST)[0] = S * (SRCB)[0]; \ 295 (DST)[1] = S * (SRCB)[1]; \ 296 (DST)[2] = S * (SRCB)[2]; \ 297 (DST)[3] = S * (SRCB)[3]; \ 298} while (0) 299 300/** In-place scalar multiplication */ 301#define SELF_SCALE_SCALAR_4V( DST, S ) \ 302do { \ 303 (DST)[0] *= S; \ 304 (DST)[1] *= S; \ 305 (DST)[2] *= S; \ 306 (DST)[3] *= S; \ 307} while (0) 308 309/** Assignment */ 310#define ASSIGN_4V( V, V0, V1, V2, V3 ) \ 311do { \ 312 V[0] = V0; \ 313 V[1] = V1; \ 314 V[2] = V2; \ 315 V[3] = V3; \ 316} while(0) 317 318/*@}*/ 319 320 321/**********************************************************************/ 322/** \name 3-element vector operations*/ 323/*@{*/ 324 325/** Zero */ 326#define ZERO_3V( DST ) (DST)[0] = (DST)[1] = (DST)[2] = 0 327 328/** Test for equality */ 329#define TEST_EQ_3V(a,b) \ 330 ((a)[0] == (b)[0] && \ 331 (a)[1] == (b)[1] && \ 332 (a)[2] == (b)[2]) 333 334/** Copy a 3-element vector */ 335#define COPY_3V( DST, SRC ) \ 336do { \ 337 (DST)[0] = (SRC)[0]; \ 338 (DST)[1] = (SRC)[1]; \ 339 (DST)[2] = (SRC)[2]; \ 340} while (0) 341 342/** Copy a 3-element vector with cast */ 343#define COPY_3V_CAST( DST, SRC, CAST ) \ 344do { \ 345 (DST)[0] = (CAST)(SRC)[0]; \ 346 (DST)[1] = (CAST)(SRC)[1]; \ 347 (DST)[2] = (CAST)(SRC)[2]; \ 348} while (0) 349 350/** Copy a 3-element float vector */ 351#define COPY_3FV( DST, SRC ) \ 352do { \ 353 const GLfloat *_tmp = (SRC); \ 354 (DST)[0] = _tmp[0]; \ 355 (DST)[1] = _tmp[1]; \ 356 (DST)[2] = _tmp[2]; \ 357} while (0) 358 359/** Subtraction */ 360#define SUB_3V( DST, SRCA, SRCB ) \ 361do { \ 362 (DST)[0] = (SRCA)[0] - (SRCB)[0]; \ 363 (DST)[1] = (SRCA)[1] - (SRCB)[1]; \ 364 (DST)[2] = (SRCA)[2] - (SRCB)[2]; \ 365} while (0) 366 367/** Addition */ 368#define ADD_3V( DST, SRCA, SRCB ) \ 369do { \ 370 (DST)[0] = (SRCA)[0] + (SRCB)[0]; \ 371 (DST)[1] = (SRCA)[1] + (SRCB)[1]; \ 372 (DST)[2] = (SRCA)[2] + (SRCB)[2]; \ 373} while (0) 374 375/** In-place scalar multiplication */ 376#define SCALE_3V( DST, SRCA, SRCB ) \ 377do { \ 378 (DST)[0] = (SRCA)[0] * (SRCB)[0]; \ 379 (DST)[1] = (SRCA)[1] * (SRCB)[1]; \ 380 (DST)[2] = (SRCA)[2] * (SRCB)[2]; \ 381} while (0) 382 383/** In-place element-wise multiplication */ 384#define SELF_SCALE_3V( DST, SRC ) \ 385do { \ 386 (DST)[0] *= (SRC)[0]; \ 387 (DST)[1] *= (SRC)[1]; \ 388 (DST)[2] *= (SRC)[2]; \ 389} while (0) 390 391/** In-place addition */ 392#define ACC_3V( DST, SRC ) \ 393do { \ 394 (DST)[0] += (SRC)[0]; \ 395 (DST)[1] += (SRC)[1]; \ 396 (DST)[2] += (SRC)[2]; \ 397} while (0) 398 399/** Element-wise multiplication and addition */ 400#define ACC_SCALE_3V( DST, SRCA, SRCB ) \ 401do { \ 402 (DST)[0] += (SRCA)[0] * (SRCB)[0]; \ 403 (DST)[1] += (SRCA)[1] * (SRCB)[1]; \ 404 (DST)[2] += (SRCA)[2] * (SRCB)[2]; \ 405} while (0) 406 407/** Scalar multiplication */ 408#define SCALE_SCALAR_3V( DST, S, SRCB ) \ 409do { \ 410 (DST)[0] = S * (SRCB)[0]; \ 411 (DST)[1] = S * (SRCB)[1]; \ 412 (DST)[2] = S * (SRCB)[2]; \ 413} while (0) 414 415/** In-place scalar multiplication and addition */ 416#define ACC_SCALE_SCALAR_3V( DST, S, SRCB ) \ 417do { \ 418 (DST)[0] += S * (SRCB)[0]; \ 419 (DST)[1] += S * (SRCB)[1]; \ 420 (DST)[2] += S * (SRCB)[2]; \ 421} while (0) 422 423/** In-place scalar multiplication */ 424#define SELF_SCALE_SCALAR_3V( DST, S ) \ 425do { \ 426 (DST)[0] *= S; \ 427 (DST)[1] *= S; \ 428 (DST)[2] *= S; \ 429} while (0) 430 431/** In-place scalar addition */ 432#define ACC_SCALAR_3V( DST, S ) \ 433do { \ 434 (DST)[0] += S; \ 435 (DST)[1] += S; \ 436 (DST)[2] += S; \ 437} while (0) 438 439/** Assignment */ 440#define ASSIGN_3V( V, V0, V1, V2 ) \ 441do { \ 442 V[0] = V0; \ 443 V[1] = V1; \ 444 V[2] = V2; \ 445} while(0) 446 447/*@}*/ 448 449 450/**********************************************************************/ 451/** \name 2-element vector operations*/ 452/*@{*/ 453 454/** Zero */ 455#define ZERO_2V( DST ) (DST)[0] = (DST)[1] = 0 456 457/** Copy a 2-element vector */ 458#define COPY_2V( DST, SRC ) \ 459do { \ 460 (DST)[0] = (SRC)[0]; \ 461 (DST)[1] = (SRC)[1]; \ 462} while (0) 463 464/** Copy a 2-element vector with cast */ 465#define COPY_2V_CAST( DST, SRC, CAST ) \ 466do { \ 467 (DST)[0] = (CAST)(SRC)[0]; \ 468 (DST)[1] = (CAST)(SRC)[1]; \ 469} while (0) 470 471/** Copy a 2-element float vector */ 472#define COPY_2FV( DST, SRC ) \ 473do { \ 474 const GLfloat *_tmp = (SRC); \ 475 (DST)[0] = _tmp[0]; \ 476 (DST)[1] = _tmp[1]; \ 477} while (0) 478 479/** Subtraction */ 480#define SUB_2V( DST, SRCA, SRCB ) \ 481do { \ 482 (DST)[0] = (SRCA)[0] - (SRCB)[0]; \ 483 (DST)[1] = (SRCA)[1] - (SRCB)[1]; \ 484} while (0) 485 486/** Addition */ 487#define ADD_2V( DST, SRCA, SRCB ) \ 488do { \ 489 (DST)[0] = (SRCA)[0] + (SRCB)[0]; \ 490 (DST)[1] = (SRCA)[1] + (SRCB)[1]; \ 491} while (0) 492 493/** In-place scalar multiplication */ 494#define SCALE_2V( DST, SRCA, SRCB ) \ 495do { \ 496 (DST)[0] = (SRCA)[0] * (SRCB)[0]; \ 497 (DST)[1] = (SRCA)[1] * (SRCB)[1]; \ 498} while (0) 499 500/** In-place addition */ 501#define ACC_2V( DST, SRC ) \ 502do { \ 503 (DST)[0] += (SRC)[0]; \ 504 (DST)[1] += (SRC)[1]; \ 505} while (0) 506 507/** Element-wise multiplication and addition */ 508#define ACC_SCALE_2V( DST, SRCA, SRCB ) \ 509do { \ 510 (DST)[0] += (SRCA)[0] * (SRCB)[0]; \ 511 (DST)[1] += (SRCA)[1] * (SRCB)[1]; \ 512} while (0) 513 514/** Scalar multiplication */ 515#define SCALE_SCALAR_2V( DST, S, SRCB ) \ 516do { \ 517 (DST)[0] = S * (SRCB)[0]; \ 518 (DST)[1] = S * (SRCB)[1]; \ 519} while (0) 520 521/** In-place scalar multiplication and addition */ 522#define ACC_SCALE_SCALAR_2V( DST, S, SRCB ) \ 523do { \ 524 (DST)[0] += S * (SRCB)[0]; \ 525 (DST)[1] += S * (SRCB)[1]; \ 526} while (0) 527 528/** In-place scalar multiplication */ 529#define SELF_SCALE_SCALAR_2V( DST, S ) \ 530do { \ 531 (DST)[0] *= S; \ 532 (DST)[1] *= S; \ 533} while (0) 534 535/** In-place scalar addition */ 536#define ACC_SCALAR_2V( DST, S ) \ 537do { \ 538 (DST)[0] += S; \ 539 (DST)[1] += S; \ 540} while (0) 541 542/** Assign scalers to short vectors */ 543#define ASSIGN_2V( V, V0, V1 ) \ 544do { \ 545 V[0] = V0; \ 546 V[1] = V1; \ 547} while(0) 548 549/*@}*/ 550 551 552/** \name Linear interpolation macros */ 553/*@{*/ 554 555/** 556 * Linear interpolation 557 * 558 * \note \p OUT argument is evaluated twice! 559 * \note Be wary of using *coord++ as an argument to any of these macros! 560 */ 561#define LINTERP(T, OUT, IN) ((OUT) + (T) * ((IN) - (OUT))) 562 563/* Can do better with integer math 564 */ 565#define INTERP_UB( t, dstub, outub, inub ) \ 566do { \ 567 GLfloat inf = UBYTE_TO_FLOAT( inub ); \ 568 GLfloat outf = UBYTE_TO_FLOAT( outub ); \ 569 GLfloat dstf = LINTERP( t, outf, inf ); \ 570 UNCLAMPED_FLOAT_TO_UBYTE( dstub, dstf ); \ 571} while (0) 572 573#define INTERP_CHAN( t, dstc, outc, inc ) \ 574do { \ 575 GLfloat inf = CHAN_TO_FLOAT( inc ); \ 576 GLfloat outf = CHAN_TO_FLOAT( outc ); \ 577 GLfloat dstf = LINTERP( t, outf, inf ); \ 578 UNCLAMPED_FLOAT_TO_CHAN( dstc, dstf ); \ 579} while (0) 580 581#define INTERP_UI( t, dstui, outui, inui ) \ 582 dstui = (GLuint) (GLint) LINTERP( (t), (GLfloat) (outui), (GLfloat) (inui) ) 583 584#define INTERP_F( t, dstf, outf, inf ) \ 585 dstf = LINTERP( t, outf, inf ) 586 587#define INTERP_4F( t, dst, out, in ) \ 588do { \ 589 dst[0] = LINTERP( (t), (out)[0], (in)[0] ); \ 590 dst[1] = LINTERP( (t), (out)[1], (in)[1] ); \ 591 dst[2] = LINTERP( (t), (out)[2], (in)[2] ); \ 592 dst[3] = LINTERP( (t), (out)[3], (in)[3] ); \ 593} while (0) 594 595#define INTERP_3F( t, dst, out, in ) \ 596do { \ 597 dst[0] = LINTERP( (t), (out)[0], (in)[0] ); \ 598 dst[1] = LINTERP( (t), (out)[1], (in)[1] ); \ 599 dst[2] = LINTERP( (t), (out)[2], (in)[2] ); \ 600} while (0) 601 602#define INTERP_4CHAN( t, dst, out, in ) \ 603do { \ 604 INTERP_CHAN( (t), (dst)[0], (out)[0], (in)[0] ); \ 605 INTERP_CHAN( (t), (dst)[1], (out)[1], (in)[1] ); \ 606 INTERP_CHAN( (t), (dst)[2], (out)[2], (in)[2] ); \ 607 INTERP_CHAN( (t), (dst)[3], (out)[3], (in)[3] ); \ 608} while (0) 609 610#define INTERP_3CHAN( t, dst, out, in ) \ 611do { \ 612 INTERP_CHAN( (t), (dst)[0], (out)[0], (in)[0] ); \ 613 INTERP_CHAN( (t), (dst)[1], (out)[1], (in)[1] ); \ 614 INTERP_CHAN( (t), (dst)[2], (out)[2], (in)[2] ); \ 615} while (0) 616 617#define INTERP_SZ( t, vec, to, out, in, sz ) \ 618do { \ 619 switch (sz) { \ 620 case 4: vec[to][3] = LINTERP( (t), (vec)[out][3], (vec)[in][3] ); \ 621 case 3: vec[to][2] = LINTERP( (t), (vec)[out][2], (vec)[in][2] ); \ 622 case 2: vec[to][1] = LINTERP( (t), (vec)[out][1], (vec)[in][1] ); \ 623 case 1: vec[to][0] = LINTERP( (t), (vec)[out][0], (vec)[in][0] ); \ 624 } \ 625} while(0) 626 627/*@}*/ 628 629 630 631/** Clamp X to [MIN,MAX] */ 632#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) ) 633 634/** Assign X to CLAMP(X, MIN, MAX) */ 635#define CLAMP_SELF(x, mn, mx) \ 636 ( (x)<(mn) ? ((x) = (mn)) : ((x)>(mx) ? ((x)=(mx)) : (x)) ) 637 638 639 640/** Minimum of two values: */ 641#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) 642 643/** Maximum of two values: */ 644#define MAX2( A, B ) ( (A)>(B) ? (A) : (B) ) 645 646/** Dot product of two 2-element vectors */ 647#define DOT2( a, b ) ( (a)[0]*(b)[0] + (a)[1]*(b)[1] ) 648 649/** Dot product of two 3-element vectors */ 650#define DOT3( a, b ) ( (a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] ) 651 652/** Dot product of two 4-element vectors */ 653#define DOT4( a, b ) ( (a)[0]*(b)[0] + (a)[1]*(b)[1] + \ 654 (a)[2]*(b)[2] + (a)[3]*(b)[3] ) 655 656/** Dot product of two 4-element vectors */ 657#define DOT4V(v,a,b,c,d) (v[0]*(a) + v[1]*(b) + v[2]*(c) + v[3]*(d)) 658 659 660/** Cross product of two 3-element vectors */ 661#define CROSS3(n, u, v) \ 662do { \ 663 (n)[0] = (u)[1]*(v)[2] - (u)[2]*(v)[1]; \ 664 (n)[1] = (u)[2]*(v)[0] - (u)[0]*(v)[2]; \ 665 (n)[2] = (u)[0]*(v)[1] - (u)[1]*(v)[0]; \ 666} while (0) 667 668 669/* Normalize a 3-element vector to unit length. */ 670#define NORMALIZE_3FV( V ) \ 671do { \ 672 GLfloat len = (GLfloat) LEN_SQUARED_3FV(V); \ 673 if (len) { \ 674 len = INV_SQRTF(len); \ 675 (V)[0] = (GLfloat) ((V)[0] * len); \ 676 (V)[1] = (GLfloat) ((V)[1] * len); \ 677 (V)[2] = (GLfloat) ((V)[2] * len); \ 678 } \ 679} while(0) 680 681#define LEN_3FV( V ) (SQRTF((V)[0]*(V)[0]+(V)[1]*(V)[1]+(V)[2]*(V)[2])) 682#define LEN_2FV( V ) (SQRTF((V)[0]*(V)[0]+(V)[1]*(V)[1])) 683 684#define LEN_SQUARED_3FV( V ) ((V)[0]*(V)[0]+(V)[1]*(V)[1]+(V)[2]*(V)[2]) 685#define LEN_SQUARED_2FV( V ) ((V)[0]*(V)[0]+(V)[1]*(V)[1]) 686 687 688/** casts to silence warnings with some compilers */ 689#define ENUM_TO_INT(E) ((GLint)(E)) 690#define ENUM_TO_FLOAT(E) ((GLfloat)(GLint)(E)) 691#define ENUM_TO_DOUBLE(E) ((GLdouble)(GLint)(E)) 692#define ENUM_TO_BOOLEAN(E) ((E) ? GL_TRUE : GL_FALSE) 693 694 695#endif 696