home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 6
/
AACD06.ISO
/
AACD
/
System
/
Mesa-3.1
/
src
/
mmath.h
< prev
next >
Wrap
C/C++ Source or Header
|
2000-01-07
|
7KB
|
287 lines
/* $Id: mmath.h,v 1.8 1999/11/08 15:29:21 brianp Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.1
*
* Copyright (C) 1999 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/* $XFree86: xc/lib/GL/mesa/src/mmath.h,v 1.2 1999/04/04 00:20:28 dawes Exp $ */
/*
* Faster arithmetic functions. If the FAST_MATH preprocessor symbol is
* defined on the command line (-DFAST_MATH) then we'll use some (hopefully)
* faster functions for sqrt(), etc.
*/
#ifndef MMATH_H
#define MMATH_H
#ifdef HAVE_CONFIG_H
#include "conf.h"
#endif
#ifndef XFree86Server
#include <math.h>
#else
#include "GL/xf86glx.h"
#endif
/*
* Set the x86 FPU control word to guarentee only 32 bits of presision
* are stored in registers. Allowing the FPU to store more introduces
* differences between situations where numbers are pulled out of memory
* vs. situations where the compiler is able to optimize register usage.
*
* In the worst case, we force the compiler to use a memory access to
* truncate the float, by specifying the 'volatile' keyword.
*/
#if defined(__linux__) && defined(__i386__)
#include <fpu_control.h>
#if !defined(_FPU_SETCW)
#define _FPU_SETCW __setfpucw
typedef unsigned short fpu_control_t;
#endif
#if !defined(_FPU_GETCW)
#define _FPU_GETCW(a) (a) = __fpu_control;
#endif
/* Set it up how we want it.
*/
#if !defined(NO_FAST_MATH)
#define START_FAST_MATH(x) \
{ \
static fpu_control_t mask = _FPU_SINGLE | _FPU_MASK_IM \
| _FPU_MASK_DM | _FPU_MASK_ZM | _FPU_MASK_OM \
| _FPU_MASK_UM | _FPU_MASK_PM; \
_FPU_GETCW( x ); \
_FPU_SETCW( mask ); \
}
#else
#define START_FAST_MATH(x) \
{ \
static fpu_control_t mask = _FPU_DEFAULT; \
_FPU_GETCW( x ); \
_FPU_SETCW( mask ); \
}
#endif
/* Put it back how the application had it.
*/
#define END_FAST_MATH(x) \
{ \
_FPU_SETCW( x ); \
}
#define HAVE_FAST_MATH
#else
#define START_FAST_MATH(x) (void)(x)
#define END_FAST_MATH(x) (void)(x)
/* The mac float really is a float, with the same precision as a
* single precision 387 float.
*/
#if defined(macintosh)
#define HAVE_FAST_MATH
#endif
#endif
/*
* Float -> Int conversion
*/
#if defined(USE_X86_ASM)
#if defined(__GNUC__) && defined(__i386__)
static __inline__ int FloatToInt(float f)
{
int r;
__asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st");
return r;
}
#elif defined(__MSC__) && defined(__WIN32__)
static __inline int FloatToInt(float f)
{
int r;
_asm {
fld f
fistp r
}
return r;
}
#endif
#else
#define FloatToInt(F) ((int) (F))
#endif
/*
* Square root
*/
extern float gl_sqrt(float x);
#ifdef FAST_MATH
# define GL_SQRT(X) gl_sqrt(X)
#else
# define GL_SQRT(X) sqrt(X)
#endif
/*
* Normalize a 3-element vector to unit length.
*/
#define NORMALIZE_3FV( V ) \
do { \
GLdouble len = LEN_SQUARED_3FV(V); \
if (len > 1e-50) { \
len = 1.0 / GL_SQRT(len); \
V[0] = (GLfloat) (V[0] * len); \
V[1] = (GLfloat) (V[1] * len); \
V[2] = (GLfloat) (V[2] * len); \
} \
} while(0)
#define LEN_3FV( V ) (GL_SQRT(V[0]*V[0]+V[1]*V[1]+V[2]*V[2]))
#define LEN_SQUARED_3FV( V ) (V[0]*V[0]+V[1]*V[1]+V[2]*V[2])
/*
* Optimization for:
* GLfloat f;
* GLubyte b = FloatToInt(CLAMP(f, 0, 1) * 255)
*/
#if defined(__i386__) || defined(__sparc__)
#define USE_IEEE
#endif
#if defined(USE_IEEE) && !defined(DEBUG)
#define IEEE_ONE 0x3f7f0000
#define CLAMP_FLOAT_COLOR(f) \
do { \
if (*(GLuint *)&f >= IEEE_ONE) \
f = (*(GLint *)&f < 0) ? 0 : 1; \
} while(0)
#define CLAMP_FLOAT_COLOR_VALUE(f) \
( (*(GLuint *)&f >= IEEE_ONE) \
? ((*(GLint *)&f < 0) ? 0 : 1) \
: f )
/*
* This function/macro is sensitive to precision. Test carefully
* if you change it.
*/
#define FLOAT_COLOR_TO_UBYTE_COLOR(b, f) \
do { \
union { GLfloat r; GLuint i; } tmp; \
tmp.r = f; \
b = ((tmp.i >= IEEE_ONE) \
? ((GLint)tmp.i < 0) ? (GLubyte)0 : (GLubyte)255 \
: (tmp.r = tmp.r*(255.0F/256.0F) + 32768.0F, \
(GLubyte)tmp.i)); \
} while (0)
#define CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(b,f) \
FLOAT_COLOR_TO_UBYTE_COLOR(b, f)
#else
#define CLAMP_FLOAT_COLOR(f) \
(void) CLAMP_SELF(f,0,1)
#define CLAMP_FLOAT_COLOR_VALUE(f) \
CLAMP(f,0,1)
#define FLOAT_COLOR_TO_UBYTE_COLOR(b, f) \
b = ((GLubyte) FloatToInt(CLAMP(f, 0.0F, 1.0F) * 255.0F))
#define CLAMPED_FLOAT_COLOR_TO_UBYTE_COLOR(b,f) \
b = ((GLubyte) FloatToInt(f * 255.0F))
#endif
extern float gl_ubyte_to_float_color_tab[256];
extern float gl_ubyte_to_float_255_color_tab[256];
#define UBYTE_COLOR_TO_FLOAT_COLOR(c) gl_ubyte_to_float_color_tab[c]
#define UBYTE_COLOR_TO_FLOAT_255_COLOR(c) gl_ubyte_to_float_255_color_tab[c]
#define UBYTE_COLOR_TO_FLOAT_255_COLOR2(f,c) \
(*(int *)&(f)) = ((int *)gl_ubyte_to_float_255_color_tab)[c]
#define UBYTE_RGBA_TO_FLOAT_RGBA(f,b) \
do { \
f[0] = UBYTE_COLOR_TO_FLOAT_COLOR(b[0]); \
f[1] = UBYTE_COLOR_TO_FLOAT_COLOR(b[1]); \
f[2] = UBYTE_COLOR_TO_FLOAT_COLOR(b[2]); \
f[3] = UBYTE_COLOR_TO_FLOAT_COLOR(b[3]); \
} while(0)
#define UBYTE_RGBA_TO_FLOAT_255_RGBA(f,b) \
do { \
f[0] = UBYTE_COLOR_TO_FLOAT_255_COLOR(b[0]); \
f[1] = UBYTE_COLOR_TO_FLOAT_255_COLOR(b[1]); \
f[2] = UBYTE_COLOR_TO_FLOAT_255_COLOR(b[2]); \
f[3] = UBYTE_COLOR_TO_FLOAT_255_COLOR(b[3]); \
} while(0)
#define FLOAT_RGBA_TO_UBYTE_RGBA(b,f) \
do { \
FLOAT_COLOR_TO_UBYTE_COLOR((b[0]),(f[0])); \
FLOAT_COLOR_TO_UBYTE_COLOR((b[1]),(f[1])); \
FLOAT_COLOR_TO_UBYTE_COLOR((b[2]),(f[2])); \
FLOAT_COLOR_TO_UBYTE_COLOR((b[3]),(f[3])); \
} while(0)
#define FLOAT_RGB_TO_UBYTE_RGB(b,f) \
do { \
FLOAT_COLOR_TO_UBYTE_COLOR(b[0],f[0]); \
FLOAT_COLOR_TO_UBYTE_COLOR(b[1],f[1]); \
FLOAT_COLOR_TO_UBYTE_COLOR(b[2],f[2]); \
} while(0)
extern void gl_init_math(void);
#endif