macros.h revision 0cb28418d06c30e431bdff515c1d36a812d5950d
1/* $Id: macros.h,v 1.25 2002/02/13 00:53:19 keithw Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 3.5 6 * 7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the "Software"), 11 * to deal in the Software without restriction, including without limitation 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 * and/or sell copies of the Software, and to permit persons to whom the 14 * Software is furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included 17 * in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 */ 26 27 28/* 29 * A collection of useful macros. 30 */ 31 32 33#ifndef MACROS_H 34#define MACROS_H 35 36 37#include "glheader.h" 38/* Do not reference mtypes.h from this file. 39 */ 40 41 42/* Limits: */ 43#define MAX_GLUSHORT 0xffff 44#define MAX_GLUINT 0xffffffff 45 46 47/* Pi */ 48#ifndef M_PI 49#define M_PI (3.1415926) 50#endif 51 52 53/* Degrees to radians conversion: */ 54#define DEG2RAD (M_PI/180.0) 55 56 57#ifndef NULL 58#define NULL 0 59#endif 60 61 62 63/* 64 * Bitmask helpers 65 */ 66#define SET_BITS(WORD, BITS) (WORD) |= (BITS) 67#define CLEAR_BITS(WORD, BITS) (WORD) &= ~(BITS) 68#define TEST_BITS(WORD, BITS) ((WORD) & (BITS)) 69 70 71/* Stepping a GLfloat pointer by a byte stride 72 */ 73#define STRIDE_F(p, i) (p = (GLfloat *)((GLubyte *)p + i)) 74#define STRIDE_UI(p, i) (p = (GLuint *)((GLubyte *)p + i)) 75#define STRIDE_4UB(p, i) (p = (GLubyte (*)[4])((GLubyte *)p + i)) 76#define STRIDE_4CHAN(p, i) (p = (GLchan (*)[4])((GLubyte *)p + i)) 77#define STRIDE_CHAN(p, i) (p = (GLchan *)((GLubyte *)p + i)) 78#define STRIDE_T(p, t, i) (p = (t)((GLubyte *)p + i)) 79 80 81#define ZERO_2V( DST ) (DST)[0] = (DST)[1] = 0 82#define ZERO_3V( DST ) (DST)[0] = (DST)[1] = (DST)[2] = 0 83#define ZERO_4V( DST ) (DST)[0] = (DST)[1] = (DST)[2] = (DST)[3] = 0 84 85 86#define TEST_EQ_4V(a,b) ((a)[0] == (b)[0] && \ 87 (a)[1] == (b)[1] && \ 88 (a)[2] == (b)[2] && \ 89 (a)[3] == (b)[3]) 90 91#define TEST_EQ_3V(a,b) ((a)[0] == (b)[0] && \ 92 (a)[1] == (b)[1] && \ 93 (a)[2] == (b)[2]) 94 95#if defined(__i386__) 96#define TEST_EQ_4UBV(DST, SRC) *((GLuint*)(DST)) == *((GLuint*)(SRC)) 97#else 98#define TEST_EQ_4UBV(DST, SRC) TEST_EQ_4V(DST, SRC) 99#endif 100 101 102 103/* Copy short vectors: */ 104#define COPY_2V( DST, SRC ) \ 105do { \ 106 (DST)[0] = (SRC)[0]; \ 107 (DST)[1] = (SRC)[1]; \ 108} while (0) 109 110#define COPY_3V( DST, SRC ) \ 111do { \ 112 (DST)[0] = (SRC)[0]; \ 113 (DST)[1] = (SRC)[1]; \ 114 (DST)[2] = (SRC)[2]; \ 115} while (0) 116 117#define COPY_4V( DST, SRC ) \ 118do { \ 119 (DST)[0] = (SRC)[0]; \ 120 (DST)[1] = (SRC)[1]; \ 121 (DST)[2] = (SRC)[2]; \ 122 (DST)[3] = (SRC)[3]; \ 123} while (0) 124 125#if defined(__i386__) 126#define COPY_4UBV(DST, SRC) \ 127do { \ 128 *((GLuint*)(DST)) = *((GLuint*)(SRC)); \ 129} while (0) 130#else 131/* The GLuint cast might fail if DST or SRC are not dword-aligned (RISC) */ 132#define COPY_4UBV(DST, SRC) \ 133do { \ 134 (DST)[0] = (SRC)[0]; \ 135 (DST)[1] = (SRC)[1]; \ 136 (DST)[2] = (SRC)[2]; \ 137 (DST)[3] = (SRC)[3]; \ 138} while (0) 139#endif 140 141#define COPY_2FV( DST, SRC ) \ 142do { \ 143 const GLfloat *_tmp = (SRC); \ 144 (DST)[0] = _tmp[0]; \ 145 (DST)[1] = _tmp[1]; \ 146} while (0) 147 148#define COPY_3FV( DST, SRC ) \ 149do { \ 150 const GLfloat *_tmp = (SRC); \ 151 (DST)[0] = _tmp[0]; \ 152 (DST)[1] = _tmp[1]; \ 153 (DST)[2] = _tmp[2]; \ 154} while (0) 155 156#define COPY_4FV( DST, SRC ) \ 157do { \ 158 const GLfloat *_tmp = (SRC); \ 159 (DST)[0] = _tmp[0]; \ 160 (DST)[1] = _tmp[1]; \ 161 (DST)[2] = _tmp[2]; \ 162 (DST)[3] = _tmp[3]; \ 163} while (0) 164 165 166 167#define COPY_SZ_4V(DST, SZ, SRC) \ 168do { \ 169 switch (SZ) { \ 170 case 4: (DST)[3] = (SRC)[3]; \ 171 case 3: (DST)[2] = (SRC)[2]; \ 172 case 2: (DST)[1] = (SRC)[1]; \ 173 case 1: (DST)[0] = (SRC)[0]; \ 174 } \ 175} while(0) 176 177#define COPY_CLEAN_4V(DST, SZ, SRC) \ 178do { \ 179 ASSIGN_4V( DST, 0, 0, 0, 1 ); \ 180 COPY_SZ_4V( DST, SZ, SRC ); \ 181} while (0) 182 183#define SUB_4V( DST, SRCA, SRCB ) \ 184do { \ 185 (DST)[0] = (SRCA)[0] - (SRCB)[0]; \ 186 (DST)[1] = (SRCA)[1] - (SRCB)[1]; \ 187 (DST)[2] = (SRCA)[2] - (SRCB)[2]; \ 188 (DST)[3] = (SRCA)[3] - (SRCB)[3]; \ 189} while (0) 190 191#define ADD_4V( DST, SRCA, SRCB ) \ 192do { \ 193 (DST)[0] = (SRCA)[0] + (SRCB)[0]; \ 194 (DST)[1] = (SRCA)[1] + (SRCB)[1]; \ 195 (DST)[2] = (SRCA)[2] + (SRCB)[2]; \ 196 (DST)[3] = (SRCA)[3] + (SRCB)[3]; \ 197} while (0) 198 199#define SCALE_4V( DST, SRCA, SRCB ) \ 200do { \ 201 (DST)[0] = (SRCA)[0] * (SRCB)[0]; \ 202 (DST)[1] = (SRCA)[1] * (SRCB)[1]; \ 203 (DST)[2] = (SRCA)[2] * (SRCB)[2]; \ 204 (DST)[3] = (SRCA)[3] * (SRCB)[3]; \ 205} while (0) 206 207#define ACC_4V( DST, SRC ) \ 208do { \ 209 (DST)[0] += (SRC)[0]; \ 210 (DST)[1] += (SRC)[1]; \ 211 (DST)[2] += (SRC)[2]; \ 212 (DST)[3] += (SRC)[3]; \ 213} while (0) 214 215#define ACC_SCALE_4V( DST, SRCA, SRCB ) \ 216do { \ 217 (DST)[0] += (SRCA)[0] * (SRCB)[0]; \ 218 (DST)[1] += (SRCA)[1] * (SRCB)[1]; \ 219 (DST)[2] += (SRCA)[2] * (SRCB)[2]; \ 220 (DST)[3] += (SRCA)[3] * (SRCB)[3]; \ 221} while (0) 222 223#define ACC_SCALE_SCALAR_4V( DST, S, SRCB ) \ 224do { \ 225 (DST)[0] += S * (SRCB)[0]; \ 226 (DST)[1] += S * (SRCB)[1]; \ 227 (DST)[2] += S * (SRCB)[2]; \ 228 (DST)[3] += S * (SRCB)[3]; \ 229} while (0) 230 231#define SCALE_SCALAR_4V( DST, S, SRCB ) \ 232do { \ 233 (DST)[0] = S * (SRCB)[0]; \ 234 (DST)[1] = S * (SRCB)[1]; \ 235 (DST)[2] = S * (SRCB)[2]; \ 236 (DST)[3] = S * (SRCB)[3]; \ 237} while (0) 238 239 240#define SELF_SCALE_SCALAR_4V( DST, S ) \ 241do { \ 242 (DST)[0] *= S; \ 243 (DST)[1] *= S; \ 244 (DST)[2] *= S; \ 245 (DST)[3] *= S; \ 246} while (0) 247 248 249/* 250 * Similarly for 3-vectors. 251 */ 252#define SUB_3V( DST, SRCA, SRCB ) \ 253do { \ 254 (DST)[0] = (SRCA)[0] - (SRCB)[0]; \ 255 (DST)[1] = (SRCA)[1] - (SRCB)[1]; \ 256 (DST)[2] = (SRCA)[2] - (SRCB)[2]; \ 257} while (0) 258 259#define ADD_3V( DST, SRCA, SRCB ) \ 260do { \ 261 (DST)[0] = (SRCA)[0] + (SRCB)[0]; \ 262 (DST)[1] = (SRCA)[1] + (SRCB)[1]; \ 263 (DST)[2] = (SRCA)[2] + (SRCB)[2]; \ 264} while (0) 265 266#define SCALE_3V( DST, SRCA, SRCB ) \ 267do { \ 268 (DST)[0] = (SRCA)[0] * (SRCB)[0]; \ 269 (DST)[1] = (SRCA)[1] * (SRCB)[1]; \ 270 (DST)[2] = (SRCA)[2] * (SRCB)[2]; \ 271} while (0) 272 273#define SELF_SCALE_3V( DST, SRC ) \ 274do { \ 275 (DST)[0] *= (SRC)[0]; \ 276 (DST)[1] *= (SRC)[1]; \ 277 (DST)[2] *= (SRC)[2]; \ 278} while (0) 279 280#define ACC_3V( DST, SRC ) \ 281do { \ 282 (DST)[0] += (SRC)[0]; \ 283 (DST)[1] += (SRC)[1]; \ 284 (DST)[2] += (SRC)[2]; \ 285} while (0) 286 287#define ACC_SCALE_3V( DST, SRCA, SRCB ) \ 288do { \ 289 (DST)[0] += (SRCA)[0] * (SRCB)[0]; \ 290 (DST)[1] += (SRCA)[1] * (SRCB)[1]; \ 291 (DST)[2] += (SRCA)[2] * (SRCB)[2]; \ 292} while (0) 293 294#define SCALE_SCALAR_3V( DST, S, SRCB ) \ 295do { \ 296 (DST)[0] = S * (SRCB)[0]; \ 297 (DST)[1] = S * (SRCB)[1]; \ 298 (DST)[2] = S * (SRCB)[2]; \ 299} while (0) 300 301#define ACC_SCALE_SCALAR_3V( DST, S, SRCB ) \ 302do { \ 303 (DST)[0] += S * (SRCB)[0]; \ 304 (DST)[1] += S * (SRCB)[1]; \ 305 (DST)[2] += S * (SRCB)[2]; \ 306} while (0) 307 308#define SELF_SCALE_SCALAR_3V( DST, S ) \ 309do { \ 310 (DST)[0] *= S; \ 311 (DST)[1] *= S; \ 312 (DST)[2] *= S; \ 313} while (0) 314 315#define ACC_SCALAR_3V( DST, S ) \ 316do { \ 317 (DST)[0] += S; \ 318 (DST)[1] += S; \ 319 (DST)[2] += S; \ 320} while (0) 321 322/* And also for 2-vectors 323 */ 324#define SUB_2V( DST, SRCA, SRCB ) \ 325do { \ 326 (DST)[0] = (SRCA)[0] - (SRCB)[0]; \ 327 (DST)[1] = (SRCA)[1] - (SRCB)[1]; \ 328} while (0) 329 330#define ADD_2V( DST, SRCA, SRCB ) \ 331do { \ 332 (DST)[0] = (SRCA)[0] + (SRCB)[0]; \ 333 (DST)[1] = (SRCA)[1] + (SRCB)[1]; \ 334} while (0) 335 336#define SCALE_2V( DST, SRCA, SRCB ) \ 337do { \ 338 (DST)[0] = (SRCA)[0] * (SRCB)[0]; \ 339 (DST)[1] = (SRCA)[1] * (SRCB)[1]; \ 340} while (0) 341 342#define ACC_2V( DST, SRC ) \ 343do { \ 344 (DST)[0] += (SRC)[0]; \ 345 (DST)[1] += (SRC)[1]; \ 346} while (0) 347 348#define ACC_SCALE_2V( DST, SRCA, SRCB ) \ 349do { \ 350 (DST)[0] += (SRCA)[0] * (SRCB)[0]; \ 351 (DST)[1] += (SRCA)[1] * (SRCB)[1]; \ 352} while (0) 353 354#define SCALE_SCALAR_2V( DST, S, SRCB ) \ 355do { \ 356 (DST)[0] = S * (SRCB)[0]; \ 357 (DST)[1] = S * (SRCB)[1]; \ 358} while (0) 359 360#define ACC_SCALE_SCALAR_2V( DST, S, SRCB ) \ 361do { \ 362 (DST)[0] += S * (SRCB)[0]; \ 363 (DST)[1] += S * (SRCB)[1]; \ 364} while (0) 365 366#define SELF_SCALE_SCALAR_2V( DST, S ) \ 367do { \ 368 (DST)[0] *= S; \ 369 (DST)[1] *= S; \ 370} while (0) 371 372#define ACC_SCALAR_2V( DST, S ) \ 373do { \ 374 (DST)[0] += S; \ 375 (DST)[1] += S; \ 376} while (0) 377 378 379 380/* Assign scalers to short vectors: */ 381#define ASSIGN_2V( V, V0, V1 ) \ 382do { \ 383 V[0] = V0; \ 384 V[1] = V1; \ 385} while(0) 386 387#define ASSIGN_3V( V, V0, V1, V2 ) \ 388do { \ 389 V[0] = V0; \ 390 V[1] = V1; \ 391 V[2] = V2; \ 392} while(0) 393 394#define ASSIGN_4V( V, V0, V1, V2, V3 ) \ 395do { \ 396 V[0] = V0; \ 397 V[1] = V1; \ 398 V[2] = V2; \ 399 V[3] = V3; \ 400} while(0) 401 402 403 404 405/* Absolute value (for Int, Float, Double): */ 406#define ABSI(X) ((X) < 0 ? -(X) : (X)) 407#define ABSF(X) ((X) < 0.0F ? -(X) : (X)) 408#define ABSD(X) ((X) < 0.0 ? -(X) : (X)) 409 410 411 412/* Round a floating-point value to the nearest integer: */ 413#define ROUNDF(X) ( (X)<0.0F ? ((GLint) ((X)-0.5F)) : ((GLint) ((X)+0.5F)) ) 414 415 416/* Compute ceiling of integer quotient of A divided by B: */ 417#define CEILING( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 ) 418 419 420/* Clamp X to [MIN,MAX]: */ 421#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) ) 422 423/* Assign X to CLAMP(X, MIN, MAX) */ 424#define CLAMP_SELF(x, mn, mx) \ 425 ( (x)<(mn) ? ((x) = (mn)) : ((x)>(mx) ? ((x)=(mx)) : (x)) ) 426 427 428 429/* Min of two values: */ 430#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) 431 432/* MAX of two values: */ 433#define MAX2( A, B ) ( (A)>(B) ? (A) : (B) ) 434 435/* Dot product of two 2-element vectors */ 436#define DOT2( a, b ) ( (a)[0]*(b)[0] + (a)[1]*(b)[1] ) 437 438/* Dot product of two 3-element vectors */ 439#define DOT3( a, b ) ( (a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] ) 440 441/* Dot product of two 4-element vectors */ 442#define DOT4( a, b ) ( (a)[0]*(b)[0] + (a)[1]*(b)[1] + \ 443 (a)[2]*(b)[2] + (a)[3]*(b)[3] ) 444 445#define DOT4V(v,a,b,c,d) (v[0]*(a) + v[1]*(b) + v[2]*(c) + v[3]*(d)) 446 447 448#define CROSS3(n, u, v) \ 449do { \ 450 (n)[0] = (u)[1]*(v)[2] - (u)[2]*(v)[1]; \ 451 (n)[1] = (u)[2]*(v)[0] - (u)[0]*(v)[2]; \ 452 (n)[2] = (u)[0]*(v)[1] - (u)[1]*(v)[0]; \ 453} while (0) 454 455 456 457/* Generic color packing macros 458 */ 459 460#define PACK_COLOR_8888( a, b, c, d ) \ 461 (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) 462 463#define PACK_COLOR_888( a, b, c ) \ 464 (((a) << 16) | ((b) << 8) | (c)) 465 466#define PACK_COLOR_565( a, b, c ) \ 467 ((((a) & 0xf8) << 8) | (((b) & 0xfc) << 3) | (((c) & 0xf8) >> 3)) 468 469#define PACK_COLOR_1555( a, b, c, d ) \ 470 ((((b) & 0xf8) << 7) | (((c) & 0xf8) << 2) | (((d) & 0xf8) >> 3) | \ 471 ((a) ? 0x8000 : 0)) 472 473#define PACK_COLOR_4444( a, b, c, d ) \ 474 ((((a) & 0xf0) << 8) | (((b) & 0xf0) << 4) | ((c) & 0xf0) | ((d) >> 4)) 475 476#define PACK_COLOR_88( a, b ) \ 477 (((a) << 8) | (b)) 478 479#define PACK_COLOR_332( a, b, c ) \ 480 (((a) & 0xe0) | (((b) & 0xe0) >> 3) | (((c) & 0xc0) >> 6)) 481 482 483#endif 484