home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / System / Mesa-3.1 / src-glu / glu.c < prev    next >
C/C++ Source or Header  |  1999-11-28  |  12KB  |  459 lines

  1. /* $Id: glu.c,v 1.16.2.2 1999/11/22 22:18:13 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.1
  6.  * Copyright (C) 1995-1999  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: glu.c,v $
  26.  * Revision 1.16.2.2  1999/11/22 22:18:13  brianp
  27.  * removed GLU_EXT_get_proc_address from ext string
  28.  *
  29.  * Revision 1.16.2.1  1999/11/19 21:22:07  brianp
  30.  * replace encounteed with encountered
  31.  *
  32.  * Revision 1.16  1999/10/27 09:47:41  brianp
  33.  * disabled gluGetProcAddressEXT
  34.  *
  35.  * Revision 1.15  1999/09/19 02:03:19  tjump
  36.  * More Win32 build compliance fixups
  37.  *
  38.  * Revision 1.14  1999/09/17 12:21:53  brianp
  39.  * glGetProcAddressEXT changes to accomodate Win32 and non-Win32
  40.  *
  41.  * Revision 1.13  1999/09/17 03:17:18  tjump
  42.  * Patch error fixup
  43.  *
  44.  * Revision 1.12  1999/09/17 03:07:28  tjump
  45.  * Win32 build req't updates
  46.  *
  47.  * Revision 1.11  1999/09/17 01:00:38  brianp
  48.  * fixed typo
  49.  *
  50.  * Revision 1.10  1999/09/17 00:06:14  brianp
  51.  * gluGetProcAddressEXT change for C++ / BeOS
  52.  *
  53.  * Revision 1.9  1999/09/16 22:37:56  brianp
  54.  * added some casts in gluGetProcAddressEXT()
  55.  *
  56.  * Revision 1.8  1999/09/16 16:53:28  brianp
  57.  * clean-up of GLU_EXT_get_proc_address
  58.  *
  59.  * Revision 1.7  1999/09/14 00:11:40  brianp
  60.  * added gluCheckExtension()
  61.  *
  62.  * Revision 1.6  1999/09/13 14:31:32  joukj
  63.  *
  64.  * strcmp needs the string.h
  65.  *
  66.  * Revision 1.5  1999/09/11 12:04:54  brianp
  67.  * added 1.2 function to gluGetProcAddressEXT()
  68.  *
  69.  * Revision 1.4  1999/09/11 11:36:26  brianp
  70.  * added GLU_EXT_get_proc_address
  71.  *
  72.  * Revision 1.3  1999/09/10 04:32:10  gareth
  73.  * Fixed triangle output, recovery process termination.
  74.  *
  75.  * Revision 1.2  1999/09/10 02:03:31  gareth
  76.  * Added GLU 1.3 tessellation (except winding rule code).
  77.  *
  78.  * Revision 1.1.1.1  1999/08/19 00:55:42  jtg
  79.  * Imported sources
  80.  *
  81.  * Revision 1.13  1999/03/31 19:07:28  brianp
  82.  * added GL_EXT_abgr to extensions
  83.  *
  84.  * Revision 1.12  1999/02/06 06:12:41  brianp
  85.  * updated version string to 3.1
  86.  *
  87.  * Revision 1.11  1999/01/03 03:23:15  brianp
  88.  * now using GLAPIENTRY and GLCALLBACK keywords (Ted Jump)
  89.  *
  90.  * Revision 1.10  1998/04/22 00:35:50  brianp
  91.  * changed version to 3.0
  92.  *
  93.  * Revision 1.9  1997/12/09 03:03:32  brianp
  94.  * changed version to 2.6
  95.  *
  96.  * Revision 1.8  1997/10/04 01:30:20  brianp
  97.  * changed version to 2.5
  98.  *
  99.  * Revision 1.7  1997/08/13 01:25:21  brianp
  100.  * changed version string to 2.4
  101.  *
  102.  * Revision 1.6  1997/07/24 01:28:44  brianp
  103.  * changed precompiled header symbol from PCH to PC_HEADER
  104.  *
  105.  * Revision 1.5  1997/07/13 22:59:11  brianp
  106.  * added const to viewport parameter of gluPickMatrix()
  107.  *
  108.  * Revision 1.4  1997/05/28 02:29:38  brianp
  109.  * added support for precompiled headers (PCH), inserted APIENTRY keyword
  110.  *
  111.  * Revision 1.3  1997/04/12 16:19:02  brianp
  112.  * changed version to 2.3
  113.  *
  114.  * Revision 1.2  1997/03/11 00:58:34  brianp
  115.  * changed version to 2.2
  116.  *
  117.  * Revision 1.1  1996/09/27 01:19:39  brianp
  118.  * Initial revision
  119.  *
  120.  */
  121.  
  122.  
  123. #ifdef PC_HEADER
  124. #include "all.h"
  125. #else
  126. #include <assert.h>
  127. #include <math.h>
  128. #include <stdio.h>
  129. #include <stdlib.h>
  130. #include <string.h>
  131. #include "gluP.h"
  132. #endif
  133.  
  134.  
  135. /*
  136.  * Miscellaneous utility functions
  137.  */
  138.  
  139.  
  140. #ifndef M_PI
  141. #define M_PI 3.1415926536
  142. #endif
  143. #define EPS 0.00001
  144.  
  145.  
  146.  
  147.  
  148. void GLAPIENTRY gluLookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez,
  149.                          GLdouble centerx, GLdouble centery, GLdouble centerz,
  150.                          GLdouble upx, GLdouble upy, GLdouble upz )
  151. {
  152.    GLdouble m[16];
  153.    GLdouble x[3], y[3], z[3];
  154.    GLdouble mag;
  155.  
  156.    /* Make rotation matrix */
  157.  
  158.    /* Z vector */
  159.    z[0] = eyex - centerx;
  160.    z[1] = eyey - centery;
  161.    z[2] = eyez - centerz;
  162.    mag = sqrt( z[0]*z[0] + z[1]*z[1] + z[2]*z[2] );
  163.    if (mag) {  /* mpichler, 19950515 */
  164.       z[0] /= mag;
  165.       z[1] /= mag;
  166.       z[2] /= mag;
  167.    }
  168.  
  169.    /* Y vector */
  170.    y[0] = upx;
  171.    y[1] = upy;
  172.    y[2] = upz;
  173.  
  174.    /* X vector = Y cross Z */
  175.    x[0] =  y[1]*z[2] - y[2]*z[1];
  176.    x[1] = -y[0]*z[2] + y[2]*z[0];
  177.    x[2] =  y[0]*z[1] - y[1]*z[0];
  178.  
  179.    /* Recompute Y = Z cross X */
  180.    y[0] =  z[1]*x[2] - z[2]*x[1];
  181.    y[1] = -z[0]*x[2] + z[2]*x[0];
  182.    y[2] =  z[0]*x[1] - z[1]*x[0];
  183.  
  184.    /* mpichler, 19950515 */
  185.    /* cross product gives area of parallelogram, which is < 1.0 for
  186.     * non-perpendicular unit-length vectors; so normalize x, y here
  187.     */
  188.  
  189.    mag = sqrt( x[0]*x[0] + x[1]*x[1] + x[2]*x[2] );
  190.    if (mag) {
  191.       x[0] /= mag;
  192.       x[1] /= mag;
  193.       x[2] /= mag;
  194.    }
  195.  
  196.    mag = sqrt( y[0]*y[0] + y[1]*y[1] + y[2]*y[2] );
  197.    if (mag) {
  198.       y[0] /= mag;
  199.       y[1] /= mag;
  200.       y[2] /= mag;
  201.    }
  202.  
  203. #define M(row,col)  m[col*4+row]
  204.    M(0,0) = x[0];  M(0,1) = x[1];  M(0,2) = x[2];  M(0,3) = 0.0;
  205.    M(1,0) = y[0];  M(1,1) = y[1];  M(1,2) = y[2];  M(1,3) = 0.0;
  206.    M(2,0) = z[0];  M(2,1) = z[1];  M(2,2) = z[2];  M(2,3) = 0.0;
  207.    M(3,0) = 0.0;   M(3,1) = 0.0;   M(3,2) = 0.0;   M(3,3) = 1.0;
  208. #undef M
  209.    glMultMatrixd( m );
  210.  
  211.    /* Translate Eye to Origin */
  212.    glTranslated( -eyex, -eyey, -eyez );
  213.  
  214. }
  215.  
  216.  
  217.  
  218. void GLAPIENTRY gluOrtho2D( GLdouble left, GLdouble right,
  219.                           GLdouble bottom, GLdouble top )
  220. {
  221.    glOrtho( left, right, bottom, top, -1.0, 1.0 );
  222. }
  223.  
  224.  
  225.  
  226. void GLAPIENTRY gluPerspective( GLdouble fovy, GLdouble aspect,
  227.                               GLdouble zNear, GLdouble zFar )
  228. {
  229.    GLdouble xmin, xmax, ymin, ymax;
  230.  
  231.    ymax = zNear * tan( fovy * M_PI / 360.0 );
  232.    ymin = -ymax;
  233.  
  234.    xmin = ymin * aspect;
  235.    xmax = ymax * aspect;
  236.  
  237.    glFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
  238. }
  239.  
  240.  
  241.  
  242. void GLAPIENTRY gluPickMatrix( GLdouble x, GLdouble y,
  243.                              GLdouble width, GLdouble height,
  244.                              const GLint viewport[4] )
  245. {
  246.    GLfloat m[16];
  247.    GLfloat sx, sy;
  248.    GLfloat tx, ty;
  249.  
  250.    sx = viewport[2] / width;
  251.    sy = viewport[3] / height;
  252.    tx = (viewport[2] + 2.0 * (viewport[0] - x)) / width;
  253.    ty = (viewport[3] + 2.0 * (viewport[1] - y)) / height;
  254.  
  255. #define M(row,col)  m[col*4+row]
  256.    M(0,0) = sx;   M(0,1) = 0.0;  M(0,2) = 0.0;  M(0,3) = tx;
  257.    M(1,0) = 0.0;  M(1,1) = sy;   M(1,2) = 0.0;  M(1,3) = ty;
  258.    M(2,0) = 0.0;  M(2,1) = 0.0;  M(2,2) = 1.0;  M(2,3) = 0.0;
  259.    M(3,0) = 0.0;  M(3,1) = 0.0;  M(3,2) = 0.0;  M(3,3) = 1.0;
  260. #undef M
  261.  
  262.    glMultMatrixf( m );
  263. }
  264.  
  265.  
  266.  
  267. const GLubyte* GLAPIENTRY gluErrorString( GLenum errorCode )
  268. {
  269.    static char *tess_error[] = {
  270.       "missing gluBeginPolygon",
  271.       "missing gluBeginContour",
  272.       "missing gluEndPolygon",
  273.       "missing gluEndContour",
  274.       "misoriented or self-intersecting loops",
  275.       "coincident vertices",
  276.       "colinear vertices",
  277.       "FIST recovery process fatal error"
  278.    };
  279.    static char *nurbs_error[] = {
  280.       "spline order un-supported",
  281.       "too few knots",
  282.       "valid knot range is empty",
  283.       "decreasing knot sequence knot",
  284.       "knot multiplicity greater than order of spline",
  285.       "endcurve() must follow bgncurve()",
  286.       "bgncurve() must precede endcurve()",
  287.       "missing or extra geometric data",
  288.       "can't draw pwlcurves",
  289.       "missing bgncurve()",
  290.       "missing bgnsurface()",
  291.       "endtrim() must precede endsurface()",
  292.       "bgnsurface() must precede endsurface()",
  293.       "curve of improper type passed as trim curve",
  294.       "bgnsurface() must precede bgntrim()",
  295.       "endtrim() must follow bgntrim()",
  296.       "bgntrim() must precede endtrim()",
  297.       "invalid or missing trim curve",
  298.       "bgntrim() must precede pwlcurve()",
  299.       "pwlcurve referenced twice",
  300.       "pwlcurve and nurbscurve mixed",
  301.       "improper usage of trim data type",
  302.       "nurbscurve referenced twice",
  303.       "nurbscurve and pwlcurve mixed",
  304.       "nurbssurface referenced twice",
  305.       "invalid property",
  306.       "endsurface() must follow bgnsurface()",
  307.       "misoriented trim curves",
  308.       "intersecting trim curves",
  309.       "UNUSED",
  310.       "unconnected trim curves",
  311.       "unknown knot error",
  312.       "negative vertex count encountered",
  313.       "negative byte-stride encountered",
  314.       "unknown type descriptor",
  315.       "null control array or knot vector",
  316.       "duplicate point on pwlcurve"
  317.    };
  318.  
  319.    /* GL Errors */
  320.    if (errorCode==GL_NO_ERROR) {
  321.       return (GLubyte *) "no error";
  322.    }
  323.    else if (errorCode==GL_INVALID_VALUE) {
  324.       return (GLubyte *) "invalid value";
  325.    }
  326.    else if (errorCode==GL_INVALID_ENUM) {
  327.       return (GLubyte *) "invalid enum";
  328.    }
  329.    else if (errorCode==GL_INVALID_OPERATION) {
  330.       return (GLubyte *) "invalid operation";
  331.    }
  332.    else if (errorCode==GL_STACK_OVERFLOW) {
  333.       return (GLubyte *) "stack overflow";
  334.    }
  335.    else if (errorCode==GL_STACK_UNDERFLOW) {
  336.       return (GLubyte *) "stack underflow";
  337.    }
  338.    else if (errorCode==GL_OUT_OF_MEMORY) {
  339.       return (GLubyte *) "out of memory";
  340.    }
  341.    /* GLU Errors */
  342.    else if (errorCode==GLU_NO_ERROR) {
  343.       return (GLubyte *) "no error";
  344.    }
  345.    else if (errorCode==GLU_INVALID_ENUM) {
  346.       return (GLubyte *) "invalid enum";
  347.    }
  348.    else if (errorCode==GLU_INVALID_VALUE) {
  349.       return (GLubyte *) "invalid value";
  350.    }
  351.    else if (errorCode==GLU_OUT_OF_MEMORY) {
  352.       return (GLubyte *) "out of memory";
  353.    }
  354.    else if (errorCode==GLU_INCOMPATIBLE_GL_VERSION) {
  355.       return (GLubyte *) "incompatible GL version";
  356.    }
  357.    else if (errorCode>=GLU_TESS_ERROR1 && errorCode<=GLU_TESS_ERROR8) {
  358.       return (GLubyte *) tess_error[errorCode-GLU_TESS_ERROR1];
  359.    }
  360.    else if (errorCode>=GLU_NURBS_ERROR1 && errorCode<=GLU_NURBS_ERROR37) {
  361.       return (GLubyte *) nurbs_error[errorCode-GLU_NURBS_ERROR1];
  362.    }
  363.    else {
  364.       return NULL;
  365.    }
  366. }
  367.  
  368.  
  369.  
  370. /*
  371.  * New in GLU 1.1
  372.  */
  373.  
  374. const GLubyte* GLAPIENTRY gluGetString( GLenum name )
  375. {
  376.    static char *extensions = "GL_EXT_abgr";
  377.    static char *version = "1.2 Mesa 3.1";
  378.  
  379.    switch (name) {
  380.       case GLU_EXTENSIONS:
  381.          return (GLubyte *) extensions;
  382.       case GLU_VERSION:
  383.      return (GLubyte *) version;
  384.       default:
  385.      return NULL;
  386.    }
  387. }
  388.  
  389.  
  390.  
  391. #if 0  /* gluGetProcAddressEXT not finalized yet! */
  392.  
  393. #ifdef __cplusplus
  394.    /* for BeOS R4.5 */
  395.    void GLAPIENTRY (*gluGetProcAddressEXT(const GLubyte *procName))(...)
  396. #else
  397.    void (GLAPIENTRY *gluGetProcAddressEXT(const GLubyte *procName))()
  398. #endif
  399. {
  400.    struct proc {
  401.       const char *name;
  402.       void *address;
  403.    };
  404.    static struct proc procTable[] = {
  405.       { "gluGetProcAddressEXT", (void *) gluGetProcAddressEXT },  /* me! */
  406.  
  407.       /* new 1.1 functions */
  408.       { "gluGetString", (void *) gluGetString },
  409.  
  410.       /* new 1.2 functions */
  411.       { "gluTessBeginPolygon", (void *) gluTessBeginPolygon },
  412.       { "gluTessBeginContour", (void *) gluTessBeginContour },
  413.       { "gluTessEndContour", (void *) gluTessEndContour },
  414.       { "gluTessEndPolygon", (void *) gluTessEndPolygon },
  415.       { "gluGetTessProperty", (void *) gluGetTessProperty },
  416.  
  417.       /* new 1.3 functions */
  418.  
  419.       { NULL, NULL }
  420.    };
  421.    GLuint i;
  422.  
  423.    for (i = 0; procTable[i].address; i++) {
  424.       if (strcmp((const char *) procName, procTable[i].name) == 0)
  425.          return (void (GLAPIENTRY *)()) procTable[i].address;
  426.    }
  427.  
  428.    return NULL;
  429. }
  430.  
  431. #endif
  432.  
  433.  
  434.  
  435. /*
  436.  * New in GLU 1.3
  437.  */
  438. GLboolean GLAPIENTRY
  439. gluCheckExtension( const char *extName, const GLubyte *extString )
  440. {
  441.    assert(extName);
  442.    assert(extString);
  443.    {
  444.       const int len = strlen(extName);
  445.       const char *start = (const char *) extString;
  446.  
  447.       while (1) {
  448.          const char *c = strstr( start, extName );
  449.          if (!c)
  450.             return GL_FALSE;
  451.  
  452.          if ((c == start || c[-1] == ' ') && (c[len] == ' ' || c[len] == 0))
  453.             return GL_TRUE;
  454.  
  455.          start = c + len;
  456.       }
  457.    }
  458. }
  459.