macros.h revision bd5cdaf4442872d3cd2ff94eeafadd481d27fcfb
1/* $Id: macros.h,v 1.5 1999/10/13 18:42:50 brianp Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 3.1 6 * 7 * Copyright (C) 1999 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 30 31/* 32 * A collection of useful macros. 33 */ 34 35 36#ifndef MACROS_H 37#define MACROS_H 38 39#if defined( XFree86LOADER ) && defined( XFree86Server ) 40#include <GL/glx_ansic.h> 41#else 42#include <math.h> 43#include <string.h> 44#endif 45 46 47#ifdef DEBUG 48# include <assert.h> 49# define ASSERT(X) assert(X) 50#else 51# define ASSERT(X) 52#endif 53 54 55#if defined(__GNUC__) 56#define INLINE __inline__ 57#elif defined(__MSC__) 58#define INLINE __inline 59#else 60#define INLINE 61#endif 62 63 64/* Stepping a GLfloat pointer by a byte stride 65 */ 66#define STRIDE_F(p, i) (p = (GLfloat *)((GLubyte *)p + i)) 67#define STRIDE_UI(p, i) (p = (GLuint *)((GLubyte *)p + i)) 68#define STRIDE_T(p, t, i) (p = (t *)((GLubyte *)p + i)) 69 70 71/* Limits: */ 72#define MAX_GLUSHORT 0xffff 73#define MAX_GLUINT 0xffffffff 74 75 76#define ZERO_2V( DST ) (DST)[0] = (DST)[1] = 0 77#define ZERO_3V( DST ) (DST)[0] = (DST)[1] = (DST)[2] = 0 78#define ZERO_4V( DST ) (DST)[0] = (DST)[1] = (DST)[2] = (DST)[3] = 0 79 80 81/* Copy short vectors: */ 82#define COPY_2V( DST, SRC ) \ 83do { \ 84 (DST)[0] = (SRC)[0]; \ 85 (DST)[1] = (SRC)[1]; \ 86} while (0) 87 88 89#define COPY_3V( DST, SRC ) \ 90do { \ 91 (DST)[0] = (SRC)[0]; \ 92 (DST)[1] = (SRC)[1]; \ 93 (DST)[2] = (SRC)[2]; \ 94} while (0) 95 96#define COPY_4V( DST, SRC ) \ 97do { \ 98 (DST)[0] = (SRC)[0]; \ 99 (DST)[1] = (SRC)[1]; \ 100 (DST)[2] = (SRC)[2]; \ 101 (DST)[3] = (SRC)[3]; \ 102} while (0) 103 104 105#define COPY_2FV( DST, SRC ) \ 106do { \ 107 const GLfloat *_tmp = (SRC); \ 108 (DST)[0] = _tmp[0]; \ 109 (DST)[1] = _tmp[1]; \ 110} while (0) 111 112 113#define COPY_3FV( DST, SRC ) \ 114do { \ 115 const GLfloat *_tmp = (SRC); \ 116 (DST)[0] = _tmp[0]; \ 117 (DST)[1] = _tmp[1]; \ 118 (DST)[2] = _tmp[2]; \ 119} while (0) 120 121#define COPY_4FV( DST, SRC ) \ 122do { \ 123 const GLfloat *_tmp = (SRC); \ 124 (DST)[0] = _tmp[0]; \ 125 (DST)[1] = _tmp[1]; \ 126 (DST)[2] = _tmp[2]; \ 127 (DST)[3] = _tmp[3]; \ 128} while (0) 129 130 131 132#define COPY_SZ_4V(DST, SZ, SRC) \ 133do { \ 134 switch (SZ) { \ 135 case 4: (DST)[3] = (SRC)[3]; \ 136 case 3: (DST)[2] = (SRC)[2]; \ 137 case 2: (DST)[1] = (SRC)[1]; \ 138 case 1: (DST)[0] = (SRC)[0]; \ 139 } \ 140} while(0) 141 142#define SUB_4V( DST, SRCA, SRCB ) \ 143do { \ 144 (DST)[0] = (SRCA)[0] - (SRCB)[0]; \ 145 (DST)[1] = (SRCA)[1] - (SRCB)[1]; \ 146 (DST)[2] = (SRCA)[2] - (SRCB)[2]; \ 147 (DST)[3] = (SRCA)[3] - (SRCB)[3]; \ 148} while (0) 149 150#define ADD_4V( DST, SRCA, SRCB ) \ 151do { \ 152 (DST)[0] = (SRCA)[0] + (SRCB)[0]; \ 153 (DST)[1] = (SRCA)[1] + (SRCB)[1]; \ 154 (DST)[2] = (SRCA)[2] + (SRCB)[2]; \ 155 (DST)[3] = (SRCA)[3] + (SRCB)[3]; \ 156} while (0) 157 158#define SCALE_4V( DST, SRCA, SRCB ) \ 159do { \ 160 (DST)[0] = (SRCA)[0] * (SRCB)[0]; \ 161 (DST)[1] = (SRCA)[1] * (SRCB)[1]; \ 162 (DST)[2] = (SRCA)[2] * (SRCB)[2]; \ 163 (DST)[3] = (SRCA)[3] * (SRCB)[3]; \ 164} while (0) 165 166#define ACC_4V( DST, SRC ) \ 167do { \ 168 (DST)[0] += (SRC)[0]; \ 169 (DST)[1] += (SRC)[1]; \ 170 (DST)[2] += (SRC)[2]; \ 171 (DST)[3] += (SRC)[3]; \ 172} while (0) 173 174#define ACC_SCALE_4V( DST, SRCA, SRCB ) \ 175do { \ 176 (DST)[0] += (SRCA)[0] * (SRCB)[0]; \ 177 (DST)[1] += (SRCA)[1] * (SRCB)[1]; \ 178 (DST)[2] += (SRCA)[2] * (SRCB)[2]; \ 179 (DST)[3] += (SRCA)[3] * (SRCB)[3]; \ 180} while (0) 181 182#define ACC_SCALE_SCALAR_4V( DST, S, SRCB ) \ 183do { \ 184 (DST)[0] += S * (SRCB)[0]; \ 185 (DST)[1] += S * (SRCB)[1]; \ 186 (DST)[2] += S * (SRCB)[2]; \ 187 (DST)[3] += S * (SRCB)[3]; \ 188} while (0) 189 190#define SCALE_SCALAR_4V( DST, S, SRCB ) \ 191do { \ 192 (DST)[0] = S * (SRCB)[0]; \ 193 (DST)[1] = S * (SRCB)[1]; \ 194 (DST)[2] = S * (SRCB)[2]; \ 195 (DST)[3] = S * (SRCB)[3]; \ 196} while (0) 197 198 199#define SELF_SCALE_SCALAR_4V( DST, S ) \ 200do { \ 201 (DST)[0] *= S; \ 202 (DST)[1] *= S; \ 203 (DST)[2] *= S; \ 204 (DST)[3] *= S; \ 205} while (0) 206 207 208/* 209 * Similarly for 3-vectors. 210 */ 211#define SUB_3V( DST, SRCA, SRCB ) \ 212do { \ 213 (DST)[0] = (SRCA)[0] - (SRCB)[0]; \ 214 (DST)[1] = (SRCA)[1] - (SRCB)[1]; \ 215 (DST)[2] = (SRCA)[2] - (SRCB)[2]; \ 216} while (0) 217 218#define ADD_3V( DST, SRCA, SRCB ) \ 219do { \ 220 (DST)[0] = (SRCA)[0] + (SRCB)[0]; \ 221 (DST)[1] = (SRCA)[1] + (SRCB)[1]; \ 222 (DST)[2] = (SRCA)[2] + (SRCB)[2]; \ 223} while (0) 224 225#define SCALE_3V( DST, SRCA, SRCB ) \ 226do { \ 227 (DST)[0] = (SRCA)[0] * (SRCB)[0]; \ 228 (DST)[1] = (SRCA)[1] * (SRCB)[1]; \ 229 (DST)[2] = (SRCA)[2] * (SRCB)[2]; \ 230} while (0) 231 232#define ACC_3V( DST, SRC ) \ 233do { \ 234 (DST)[0] += (SRC)[0]; \ 235 (DST)[1] += (SRC)[1]; \ 236 (DST)[2] += (SRC)[2]; \ 237} while (0) 238 239#define ACC_SCALE_3V( DST, SRCA, SRCB ) \ 240do { \ 241 (DST)[0] += (SRCA)[0] * (SRCB)[0]; \ 242 (DST)[1] += (SRCA)[1] * (SRCB)[1]; \ 243 (DST)[2] += (SRCA)[2] * (SRCB)[2]; \ 244} while (0) 245 246#define SCALE_SCALAR_3V( DST, S, SRCB ) \ 247do { \ 248 (DST)[0] = S * (SRCB)[0]; \ 249 (DST)[1] = S * (SRCB)[1]; \ 250 (DST)[2] = S * (SRCB)[2]; \ 251} while (0) 252 253#define ACC_SCALE_SCALAR_3V( DST, S, SRCB ) \ 254do { \ 255 (DST)[0] += S * (SRCB)[0]; \ 256 (DST)[1] += S * (SRCB)[1]; \ 257 (DST)[2] += S * (SRCB)[2]; \ 258} while (0) 259 260#define SELF_SCALE_SCALAR_3V( DST, S ) \ 261do { \ 262 (DST)[0] *= S; \ 263 (DST)[1] *= S; \ 264 (DST)[2] *= S; \ 265} while (0) 266 267#define ACC_SCALAR_3V( DST, S ) \ 268do { \ 269 (DST)[0] += S; \ 270 (DST)[1] += S; \ 271 (DST)[2] += S; \ 272} while (0) 273 274/* And also for 2-vectors 275 */ 276#define SUB_2V( DST, SRCA, SRCB ) \ 277do { \ 278 (DST)[0] = (SRCA)[0] - (SRCB)[0]; \ 279 (DST)[1] = (SRCA)[1] - (SRCB)[1]; \ 280} while (0) 281 282#define ADD_2V( DST, SRCA, SRCB ) \ 283do { \ 284 (DST)[0] = (SRCA)[0] + (SRCB)[0]; \ 285 (DST)[1] = (SRCA)[1] + (SRCB)[1]; \ 286} while (0) 287 288#define SCALE_2V( DST, SRCA, SRCB ) \ 289do { \ 290 (DST)[0] = (SRCA)[0] * (SRCB)[0]; \ 291 (DST)[1] = (SRCA)[1] * (SRCB)[1]; \ 292} while (0) 293 294#define ACC_2V( DST, SRC ) \ 295do { \ 296 (DST)[0] += (SRC)[0]; \ 297 (DST)[1] += (SRC)[1]; \ 298} while (0) 299 300#define ACC_SCALE_2V( DST, SRCA, SRCB ) \ 301do { \ 302 (DST)[0] += (SRCA)[0] * (SRCB)[0]; \ 303 (DST)[1] += (SRCA)[1] * (SRCB)[1]; \ 304} while (0) 305 306#define SCALE_SCALAR_2V( DST, S, SRCB ) \ 307do { \ 308 (DST)[0] = S * (SRCB)[0]; \ 309 (DST)[1] = S * (SRCB)[1]; \ 310} while (0) 311 312#define ACC_SCALE_SCALAR_2V( DST, S, SRCB ) \ 313do { \ 314 (DST)[0] += S * (SRCB)[0]; \ 315 (DST)[1] += S * (SRCB)[1]; \ 316} while (0) 317 318#define SELF_SCALE_SCALAR_2V( DST, S ) \ 319do { \ 320 (DST)[0] *= S; \ 321 (DST)[1] *= S; \ 322} while (0) 323 324#define ACC_SCALAR_2V( DST, S ) \ 325do { \ 326 (DST)[0] += S; \ 327 (DST)[1] += S; \ 328} while (0) 329 330 331 332/* 333 * Copy a vector of 4 GLubytes from SRC to DST. 334 */ 335#define COPY_4UBV(DST, SRC) \ 336do { \ 337 if (sizeof(GLuint)==4*sizeof(GLubyte)) { \ 338 *((GLuint*)(DST)) = *((GLuint*)(SRC)); \ 339 } \ 340 else { \ 341 (DST)[0] = (SRC)[0]; \ 342 (DST)[1] = (SRC)[1]; \ 343 (DST)[2] = (SRC)[2]; \ 344 (DST)[3] = (SRC)[3]; \ 345 } \ 346} while (0) 347 348 349/* Assign scalers to short vectors: */ 350#define ASSIGN_2V( V, V0, V1 ) \ 351do { V[0] = V0; V[1] = V1; } while(0) 352 353#define ASSIGN_3V( V, V0, V1, V2 ) \ 354do { V[0] = V0; V[1] = V1; V[2] = V2; } while(0) 355 356#define ASSIGN_4V( V, V0, V1, V2, V3 ) \ 357do { \ 358 V[0] = V0; \ 359 V[1] = V1; \ 360 V[2] = V2; \ 361 V[3] = V3; \ 362} while(0) 363 364 365 366 367/* Absolute value (for Int, Float, Double): */ 368#define ABSI(X) ((X) < 0 ? -(X) : (X)) 369#define ABSF(X) ((X) < 0.0F ? -(X) : (X)) 370#define ABSD(X) ((X) < 0.0 ? -(X) : (X)) 371 372 373 374/* Round a floating-point value to the nearest integer: */ 375#define ROUNDF(X) ( (X)<0.0F ? ((GLint) ((X)-0.5F)) : ((GLint) ((X)+0.5F)) ) 376 377 378/* Compute ceiling of integer quotient of A divided by B: */ 379#define CEILING( A, B ) ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 ) 380 381 382/* Clamp X to [MIN,MAX]: */ 383#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) ) 384 385/* Assign X to CLAMP(X, MIN, MAX) */ 386#define CLAMP_SELF(x, mn, mx) \ 387 ( (x)<(mn) ? ((x) = (mn)) : ((x)>(mx) ? ((x)=(mx)) : (x)) ) 388 389 390 391/* Min of two values: */ 392#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) 393 394 395/* MAX of two values: */ 396#define MAX2( A, B ) ( (A)>(B) ? (A) : (B) ) 397 398/* Dot product of two 2-element vectors */ 399#define DOT2( a, b ) ( (a)[0]*(b)[0] + (a)[1]*(b)[1] ) 400 401/* Dot product of two 3-element vectors */ 402#define DOT3( a, b ) ( (a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] ) 403 404 405/* Dot product of two 4-element vectors */ 406#define DOT4( a, b ) ( (a)[0]*(b)[0] + (a)[1]*(b)[1] + \ 407 (a)[2]*(b)[2] + (a)[3]*(b)[3] ) 408 409#define DOT4V(v,a,b,c,d) (v[0]*a + v[1]*b + v[2]*c + v[3]*d) 410 411 412#define CROSS3(n, u, v) \ 413do { \ 414 (n)[0] = (u)[1]*(v)[2] - (u)[2]*(v)[1]; \ 415 (n)[1] = (u)[2]*(v)[0] - (u)[0]*(v)[2]; \ 416 (n)[2] = (u)[0]*(v)[1] - (u)[1]*(v)[0]; \ 417} while (0) 418 419 420/* 421 * Integer / float conversion for colors, normals, etc. 422 */ 423 424 425 426 427#define BYTE_TO_UBYTE(b) (b < 0 ? 0 : (GLubyte) b) 428#define SHORT_TO_UBYTE(s) (s < 0 ? 0 : (GLubyte) (s >> 7)) 429#define USHORT_TO_UBYTE(s) (GLubyte) (s >> 8) 430#define INT_TO_UBYTE(i) (i < 0 ? 0 : (GLubyte) (i >> 23)) 431#define UINT_TO_UBYTE(i) (GLubyte) (i >> 24) 432 433 434 435 436/* Convert GLubyte in [0,255] to GLfloat in [0.0,1.0] */ 437#define UBYTE_TO_FLOAT(B) ((GLfloat) (B) * (1.0F / 255.0F)) 438 439/* Convert GLfloat in [0.0,1.0] to GLubyte in [0,255] */ 440#define FLOAT_TO_UBYTE(X) ((GLubyte) (GLint) (((X)) * 255.0F)) 441 442 443/* Convert GLbyte in [-128,127] to GLfloat in [-1.0,1.0] */ 444#define BYTE_TO_FLOAT(B) ((2.0F * (B) + 1.0F) * (1.0F/255.0F)) 445 446/* Convert GLfloat in [-1.0,1.0] to GLbyte in [-128,127] */ 447#define FLOAT_TO_BYTE(X) ( (((GLint) (255.0F * (X))) - 1) / 2 ) 448 449 450/* Convert GLushort in [0,65536] to GLfloat in [0.0,1.0] */ 451#define USHORT_TO_FLOAT(S) ((GLfloat) (S) * (1.0F / 65535.0F)) 452 453/* Convert GLfloat in [0.0,1.0] to GLushort in [0,65536] */ 454#define FLOAT_TO_USHORT(X) ((GLushort) (GLint) ((X) * 65535.0F)) 455 456 457/* Convert GLshort in [-32768,32767] to GLfloat in [-1.0,1.0] */ 458#define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F)) 459 460/* Convert GLfloat in [0.0,1.0] to GLshort in [-32768,32767] */ 461#define FLOAT_TO_SHORT(X) ( (((GLint) (65535.0F * (X))) - 1) / 2 ) 462 463 464/* Convert GLuint in [0,4294967295] to GLfloat in [0.0,1.0] */ 465#define UINT_TO_FLOAT(U) ((GLfloat) (U) * (1.0F / 4294967295.0F)) 466 467/* Convert GLfloat in [0.0,1.0] to GLuint in [0,4294967295] */ 468#define FLOAT_TO_UINT(X) ((GLuint) ((X) * 4294967295.0)) 469 470 471/* Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0] */ 472#define INT_TO_FLOAT(I) ((2.0F * (I) + 1.0F) * (1.0F/4294967294.0F)) 473 474/* Convert GLfloat in [-1.0,1.0] to GLint in [-2147483648,2147483647] */ 475/* causes overflow: 476#define FLOAT_TO_INT(X) ( (((GLint) (4294967294.0F * (X))) - 1) / 2 ) 477*/ 478/* a close approximation: */ 479#define FLOAT_TO_INT(X) ( (GLint) (2147483647.0 * (X)) ) 480 481 482 483/* 484 * Memory allocation 485 * XXX these should probably go into a new glmemory.h file. 486 */ 487#ifdef DEBUG 488extern void *gl_malloc(size_t bytes); 489extern void *gl_calloc(size_t bytes); 490extern void gl_free(void *ptr); 491#define MALLOC(BYTES) gl_malloc(BYTES) 492#define CALLOC(BYTES) gl_calloc(BYTES) 493#define MALLOC_STRUCT(T) (struct T *) gl_malloc(sizeof(struct T)) 494#define CALLOC_STRUCT(T) (struct T *) gl_calloc(sizeof(struct T)) 495#define FREE(PTR) gl_free(PTR) 496#else 497#define MALLOC(BYTES) (void *) malloc(BYTES) 498#define CALLOC(BYTES) (void *) calloc(1, BYTES) 499#define MALLOC_STRUCT(T) (struct T *) malloc(sizeof(struct T)) 500#define CALLOC_STRUCT(T) (struct T *) calloc(1,sizeof(struct T)) 501#define FREE(PTR) free(PTR) 502#endif 503 504 505/* Memory copy: */ 506#ifdef SUNOS4 507#define MEMCPY( DST, SRC, BYTES) \ 508 memcpy( (char *) (DST), (char *) (SRC), (int) (BYTES) ) 509#else 510#define MEMCPY( DST, SRC, BYTES) \ 511 memcpy( (void *) (DST), (void *) (SRC), (size_t) (BYTES) ) 512#endif 513 514 515/* Memory set: */ 516#ifdef SUNOS4 517#define MEMSET( DST, VAL, N ) \ 518 memset( (char *) (DST), (int) (VAL), (int) (N) ) 519#else 520#define MEMSET( DST, VAL, N ) \ 521 memset( (void *) (DST), (int) (VAL), (size_t) (N) ) 522#endif 523 524 525/* MACs and BeOS don't support static larger than 32kb, so... */ 526#if defined(macintosh) && !defined(__MRC__) 527 extern char *AGLAlloc(int size); 528 extern void AGLFree(char* ptr); 529# define DEFARRAY(TYPE,NAME,SIZE) TYPE *NAME = (TYPE*)AGLAlloc(sizeof(TYPE)*(SIZE)) 530# define DEFMARRAY(TYPE,NAME,SIZE1,SIZE2) TYPE (*NAME)[SIZE2] = (TYPE(*)[SIZE2])AGLAlloc(sizeof(TYPE)*(SIZE1)*(SIZE2)) 531# define CHECKARRAY(NAME,CMD) do {if (!(NAME)) {CMD;}} while (0) 532# define UNDEFARRAY(NAME) do {if ((NAME)) {AGLFree((char*)NAME);} }while (0) 533#elif defined(__BEOS__) 534# define DEFARRAY(TYPE,NAME,SIZE) TYPE *NAME = (TYPE*)malloc(sizeof(TYPE)*(SIZE)) 535# define DEFMARRAY(TYPE,NAME,SIZE1,SIZE2) TYPE (*NAME)[SIZE2] = (TYPE(*)[SIZE2])malloc(sizeof(TYPE)*(SIZE1)*(SIZE2)) 536# define CHECKARRAY(NAME,CMD) do {if (!(NAME)) {CMD;}} while (0) 537# define UNDEFARRAY(NAME) do {if ((NAME)) {free((char*)NAME);} }while (0) 538#else 539# define DEFARRAY(TYPE,NAME,SIZE) TYPE NAME[SIZE] 540# define DEFMARRAY(TYPE,NAME,SIZE1,SIZE2) TYPE NAME[SIZE1][SIZE2] 541# define CHECKARRAY(NAME,CMD) do {} while(0) 542# define UNDEFARRAY(NAME) 543#endif 544 545 546/* Some compilers don't like some of Mesa's const usage */ 547#ifdef NO_CONST 548# define CONST 549#else 550# define CONST const 551#endif 552 553 554 555/* Pi */ 556#ifndef M_PI 557#define M_PI (3.1415926) 558#endif 559 560 561/* Degrees to radians conversion: */ 562#define DEG2RAD (M_PI/180.0) 563 564 565#ifndef NULL 566#define NULL 0 567#endif 568 569 570 571#endif /*MACROS_H*/ 572