home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / System / Mesa-3.1 / src / mmath.h < prev    next >
C/C++ Source or Header  |  2000-01-07  |  7KB  |  287 lines

  1. /* $Id: mmath.h,v 1.8 1999/11/08 15:29:21 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. /* $XFree86: xc/lib/GL/mesa/src/mmath.h,v 1.2 1999/04/04 00:20:28 dawes Exp $ */
  27.  
  28.  
  29.  
  30.  
  31.  
  32. /*
  33.  * Faster arithmetic functions.  If the FAST_MATH preprocessor symbol is
  34.  * defined on the command line (-DFAST_MATH) then we'll use some (hopefully)
  35.  * faster functions for sqrt(), etc.
  36.  */
  37.  
  38.  
  39. #ifndef MMATH_H
  40. #define MMATH_H
  41.  
  42. #ifdef HAVE_CONFIG_H
  43. #include "conf.h"
  44. #endif
  45.  
  46. #ifndef XFree86Server
  47. #include <math.h>
  48. #else
  49. #include "GL/xf86glx.h"
  50. #endif
  51.  
  52. /*
  53.  * Set the x86 FPU control word to guarentee only 32 bits of presision
  54.  * are stored in registers.  Allowing the FPU to store more introduces
  55.  * differences between situations where numbers are pulled out of memory
  56.  * vs. situations where the compiler is able to optimize register usage.
  57.  * 
  58.  * In the worst case, we force the compiler to use a memory access to
  59.  * truncate the float, by specifying the 'volatile' keyword.
  60.  */
  61. #if defined(__linux__) && defined(__i386__)
  62. #include <fpu_control.h>
  63.  
  64. #if !defined(_FPU_SETCW)
  65. #define _FPU_SETCW __setfpucw
  66. typedef unsigned short fpu_control_t;
  67. #endif
  68.  
  69. #if !defined(_FPU_GETCW)
  70. #define _FPU_GETCW(a) (a) = __fpu_control;
  71. #endif
  72.  
  73. /* Set it up how we want it.
  74.  */
  75. #if !defined(NO_FAST_MATH) 
  76. #define START_FAST_MATH(x)                    \
  77.    {                                \
  78.       static fpu_control_t mask = _FPU_SINGLE | _FPU_MASK_IM    \
  79.             | _FPU_MASK_DM | _FPU_MASK_ZM | _FPU_MASK_OM    \
  80.             | _FPU_MASK_UM | _FPU_MASK_PM;            \
  81.       _FPU_GETCW( x );                        \
  82.       _FPU_SETCW( mask );                    \
  83.    }
  84. #else
  85. #define START_FAST_MATH(x)            \
  86.    {                        \
  87.       static fpu_control_t mask = _FPU_DEFAULT;    \
  88.       _FPU_GETCW( x );                \
  89.       _FPU_SETCW( mask );            \
  90.    }
  91. #endif
  92.  
  93. /* Put it back how the application had it.
  94.  */
  95. #define END_FAST_MATH(x)            \
  96.    {                        \
  97.       _FPU_SETCW( x );                \
  98.    }
  99.  
  100. #define HAVE_FAST_MATH
  101.  
  102. #else
  103. #define START_FAST_MATH(x) (void)(x)
  104. #define END_FAST_MATH(x)   (void)(x)
  105.  
  106. /* The mac float really is a float, with the same precision as a
  107.  * single precision 387 float.
  108.  */
  109. #if defined(macintosh)
  110. #define HAVE_FAST_MATH
  111. #endif
  112.  
  113. #endif
  114.  
  115.  
  116.  
  117. /*
  118.  * Float -> Int conversion
  119.  */
  120.  
  121. #if defined(USE_X86_ASM)
  122. #if defined(__GNUC__) && defined(__i386__)
  123. static __inline__ int FloatToInt(float f)
  124. {
  125.    int r;
  126.    __asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st");
  127.    return r;
  128. }
  129. #elif  defined(__MSC__) && defined(__WIN32__)
  130. static __inline int FloatToInt(float f)
  131. {
  132.    int r;
  133.    _asm {
  134.      fld f
  135.      fistp r
  136.     }
  137.    return r;
  138. }
  139. #endif
  140. #else
  141. #define FloatToInt(F) ((int) (F))
  142. #endif
  143.  
  144.  
  145.  
  146.  
  147.  
  148. /*
  149.  * Square root
  150.  */
  151.  
  152. extern float gl_sqrt(float x);
  153.  
  154. #ifdef FAST_MATH
  155. #  define GL_SQRT(X)  gl_sqrt(X)
  156. #else
  157. #  define GL_SQRT(X)  sqrt(X)
  158. #endif
  159.  
  160.  
  161.  
  162. /*
  163.  * Normalize a 3-element vector to unit length.
  164.  */
  165. #define NORMALIZE_3FV( V )            \
  166. do {                        \
  167.    GLdouble len = LEN_SQUARED_3FV(V);        \
  168.    if (len > 1e-50) {                \
  169.       len = 1.0 / GL_SQRT(len);            \
  170.       V[0] = (GLfloat) (V[0] * len);        \
  171.       V[1] = (GLfloat) (V[1] * len);        \
  172.       V[2] = (GLfloat) (V[2] * len);        \
  173.    }                        \
  174. } while(0)
  175.  
  176. #define LEN_3FV( V ) (GL_SQRT(V[0]*V[0]+V[1]*V[1]+V[2]*V[2]))
  177.  
  178. #define LEN_SQUARED_3FV( V ) (V[0]*V[0]+V[1]*V[1]+V[2]*V[2])
  179.  
  180. /*
  181.  * Optimization for:
  182.  * GLfloat f;
  183.  * GLubyte b = FloatToInt(CLAMP(f, 0, 1) * 255)
  184.  */
  185.  
  186. #if defined(__i386__) || defined(__sparc__)
  187. #define USE_IEEE
  188. #endif
  189.  
  190. #if defined(USE_IEEE) && !defined(DEBUG)
  191.  
  192. #define IEEE_ONE 0x3f7f0000
  193.  
  194. #define CLAMP_FLOAT_COLOR(f)            \
  195.     do {                    \
  196.        if (*(GLuint *)&f >= IEEE_ONE)    \
  197.           f = (*(GLint *)&f < 0) ? 0 : 1;    \
  198.     } while(0)
  199.  
  200. #define CLAMP_FLOAT_COLOR_VALUE(f)        \
  201.     ( (*(GLuint *)&f >= IEEE_ONE)        \
  202.       ? ((*(GLint *)&f < 0) ? 0 : 1)        \
  203.       : f )
  204.  
  205. /* 
  206.  * This function/macro is sensitive to precision.  Test carefully
  207.  * if you change it.
  208.  */
  209. #define FLOAT_COLOR_TO_UBYTE_COLOR(b, f)                        \
  210.         do {                                                    \
  211.            union { GLfloat r; GLuint i; } tmp;                  \
  212.            tmp.r = f;                                           \
  213.            b = ((tmp.i >= IEEE_ONE)                             \
  214.                ? ((GLint)tmp.i < 0) ? (GLubyte)0 : (GLubyte)255 \
  215.                : (tmp.r = tmp.r*(255.0F/256.0F) + 32768.0F,     \
  216.                   (GLubyte)tmp.i));                             \
  217.         } while (0)
  218.  
  219.  
  220. #define CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(b,f) \
  221.          FLOAT_COLOR_TO_UBYTE_COLOR(b, f)
  222.  
  223. #else
  224.  
  225. #define CLAMP_FLOAT_COLOR(f) \
  226.         (void) CLAMP_SELF(f,0,1)
  227.  
  228. #define CLAMP_FLOAT_COLOR_VALUE(f) \
  229.         CLAMP(f,0,1)
  230.        
  231. #define FLOAT_COLOR_TO_UBYTE_COLOR(b, f)            \
  232.     b = ((GLubyte) FloatToInt(CLAMP(f, 0.0F, 1.0F) * 255.0F))
  233.  
  234. #define CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(b,f) \
  235.     b = ((GLubyte) FloatToInt(f * 255.0F))
  236.  
  237. #endif
  238.  
  239.  
  240. extern float gl_ubyte_to_float_color_tab[256];
  241. extern float gl_ubyte_to_float_255_color_tab[256];
  242. #define UBYTE_COLOR_TO_FLOAT_COLOR(c) gl_ubyte_to_float_color_tab[c]
  243.  
  244. #define UBYTE_COLOR_TO_FLOAT_255_COLOR(c) gl_ubyte_to_float_255_color_tab[c]
  245.  
  246. #define UBYTE_COLOR_TO_FLOAT_255_COLOR2(f,c) \
  247.     (*(int *)&(f)) = ((int *)gl_ubyte_to_float_255_color_tab)[c]
  248.  
  249.  
  250. #define UBYTE_RGBA_TO_FLOAT_RGBA(f,b)         \
  251. do {                        \
  252.    f[0] = UBYTE_COLOR_TO_FLOAT_COLOR(b[0]);    \
  253.    f[1] = UBYTE_COLOR_TO_FLOAT_COLOR(b[1]);    \
  254.    f[2] = UBYTE_COLOR_TO_FLOAT_COLOR(b[2]);    \
  255.    f[3] = UBYTE_COLOR_TO_FLOAT_COLOR(b[3]);    \
  256. } while(0)
  257.  
  258.  
  259. #define UBYTE_RGBA_TO_FLOAT_255_RGBA(f,b)         \
  260. do {                        \
  261.    f[0] = UBYTE_COLOR_TO_FLOAT_255_COLOR(b[0]);    \
  262.    f[1] = UBYTE_COLOR_TO_FLOAT_255_COLOR(b[1]);    \
  263.    f[2] = UBYTE_COLOR_TO_FLOAT_255_COLOR(b[2]);    \
  264.    f[3] = UBYTE_COLOR_TO_FLOAT_255_COLOR(b[3]);    \
  265. } while(0)
  266.  
  267. #define FLOAT_RGBA_TO_UBYTE_RGBA(b,f)         \
  268. do {                        \
  269.    FLOAT_COLOR_TO_UBYTE_COLOR((b[0]),(f[0]));    \
  270.    FLOAT_COLOR_TO_UBYTE_COLOR((b[1]),(f[1]));    \
  271.    FLOAT_COLOR_TO_UBYTE_COLOR((b[2]),(f[2]));    \
  272.    FLOAT_COLOR_TO_UBYTE_COLOR((b[3]),(f[3]));    \
  273. } while(0)
  274.  
  275. #define FLOAT_RGB_TO_UBYTE_RGB(b,f)         \
  276. do {                        \
  277.    FLOAT_COLOR_TO_UBYTE_COLOR(b[0],f[0]);    \
  278.    FLOAT_COLOR_TO_UBYTE_COLOR(b[1],f[1]);    \
  279.    FLOAT_COLOR_TO_UBYTE_COLOR(b[2],f[2]);    \
  280. } while(0)
  281.  
  282.  
  283. extern void gl_init_math(void);
  284.  
  285.  
  286. #endif
  287.