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