home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / System / Mesa-3.1 / src-glu / nurbs.c < prev    next >
C/C++ Source or Header  |  1999-08-18  |  21KB  |  716 lines

  1. /* $Id: nurbs.c,v 1.1.1.1 1999/08/19 00:55:42 jtg 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: nurbs.c,v $
  26.  * Revision 1.1.1.1  1999/08/19 00:55:42  jtg
  27.  * Imported sources
  28.  *
  29.  * Revision 1.14  1999/01/03 03:23:15  brianp
  30.  * now using GLAPIENTRY and GLCALLBACK keywords (Ted Jump)
  31.  *
  32.  * Revision 1.13  1998/06/01 01:07:49  brianp
  33.  * small update for Next/OpenStep from Alexander Mai
  34.  *
  35.  * Revision 1.12  1998/03/15 18:14:30  brianp
  36.  * fixed a compiler cast warning
  37.  *
  38.  * Revision 1.11  1998/02/07 14:29:11  brianp
  39.  * fixed casting problem in gluNurbsCallback, again
  40.  *
  41.  * Revision 1.10  1998/02/04 00:21:20  brianp
  42.  * fixed cygnus compilation problem (Stephane Rehel)
  43.  *
  44.  * Revision 1.9  1998/01/16 03:35:26  brianp
  45.  * fixed Windows compilation warnings (Theodore Jump)
  46.  *
  47.  * Revision 1.8  1997/09/17 01:51:48  brianp
  48.  * changed glu*Callback() functions to match prototype in glu.h
  49.  *
  50.  * Revision 1.7  1997/07/24 01:28:44  brianp
  51.  * changed precompiled header symbol from PCH to PC_HEADER
  52.  *
  53.  * Revision 1.6  1997/07/24 01:26:31  brianp
  54.  * added CALLBACK keyword to gluNurbsCallback()
  55.  *
  56.  * Revision 1.5  1997/05/28 02:29:38  brianp
  57.  * added support for precompiled headers (PCH), inserted APIENTRY keyword
  58.  *
  59.  * Revision 1.4  1997/05/27 03:17:22  brianp
  60.  * minor clean-up
  61.  *
  62.  * Revision 1.3  1997/05/27 03:00:16  brianp
  63.  * incorporated Bogdan's new NURBS code
  64.  *
  65.  * Revision 1.2  1996/09/27 23:11:23  brianp
  66.  * ifdef'd out unimplemented trimmed nurbs code
  67.  *
  68.  * Revision 1.1  1996/09/27 01:19:39  brianp
  69.  * Initial revision
  70.  *
  71.  */
  72.  
  73.  
  74. /*
  75.  * NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
  76.  * See README2 for more info.
  77.  */
  78.  
  79. #ifdef PC_HEADER
  80. #include "all.h"
  81. #else
  82. #include <stdio.h>
  83. #include <stdlib.h>
  84. #include "gluP.h"
  85. #include "nurbs.h"
  86. #endif
  87.  
  88.  
  89. void
  90. call_user_error( GLUnurbsObj *nobj, GLenum error )
  91. {
  92.     nobj->error=error;
  93.     if(nobj->error_callback != NULL) {
  94.         (*(nobj->error_callback))(error);
  95.     }
  96.     else {
  97.        printf("NURBS error %d %s\n", error, (char *) gluErrorString(error) );
  98.     }
  99. }
  100.  
  101.  
  102.  
  103. GLUnurbsObj * GLAPIENTRY gluNewNurbsRenderer( void )
  104. {
  105.    GLUnurbsObj *n;
  106.    GLfloat tmp_viewport[4];
  107.    GLint i,j;
  108.  
  109.    n = (GLUnurbsObj *) malloc( sizeof(GLUnurbsObj) );
  110.    if (n) {
  111.       /* init */
  112.       n->culling=GL_FALSE;
  113.       n->nurbs_type=GLU_NURBS_NONE;
  114.       n->error=GLU_NO_ERROR;
  115.       n->error_callback=NULL;
  116.       n->auto_load_matrix=GL_TRUE;
  117.       n->sampling_tolerance=50.0;
  118.       n->parametric_tolerance=0.5;
  119.       n->u_step = n->v_step = 100;
  120.       n->sampling_method = GLU_PATH_LENGTH;
  121.       n->display_mode=GLU_FILL;
  122.       /* in case the user doesn't supply the sampling matrices */
  123.       /* set projection and modelview to identity */
  124.       for(i=0;i<4;i++)
  125.           for(j=0;j<4;j++)
  126.               if(i==j)
  127.               {
  128.                 n->sampling_matrices.model[i*4+j]=1.0;
  129.                 n->sampling_matrices.proj[i*4+j]=1.0;
  130.             }
  131.             else
  132.               {
  133.                 n->sampling_matrices.model[i*4+j]=0.0;
  134.                 n->sampling_matrices.proj[i*4+j]=0.0;
  135.             }
  136.       /* and set the viewport sampling matrix to current ciewport */
  137.       glGetFloatv(GL_VIEWPORT,tmp_viewport);
  138.       for(i=0;i<4;i++)
  139.           n->sampling_matrices.viewport[i]=tmp_viewport[i];
  140.       n->trim=NULL;
  141.    }
  142.    return n;
  143. }
  144.  
  145.  
  146.  
  147. void GLAPIENTRY gluDeleteNurbsRenderer( GLUnurbsObj *nobj )
  148. {
  149.    if (nobj) {
  150.       free( nobj );
  151.    }
  152. }
  153.  
  154.  
  155.  
  156. void GLAPIENTRY gluLoadSamplingMatrices( GLUnurbsObj *nobj,
  157.                   const GLfloat modelMatrix[16],
  158.                   const GLfloat projMatrix[16],
  159.                   const GLint viewport[4] )
  160. {
  161.     GLint    i;
  162.  
  163.     for(i=0;i<16;i++)
  164.     {
  165.         nobj->sampling_matrices.model[i]=modelMatrix[i];
  166.         nobj->sampling_matrices.proj[i]=projMatrix[i];
  167.     }
  168.     for(i=0;i<4;i++)
  169.         nobj->sampling_matrices.viewport[i]=viewport[i];
  170. }
  171.  
  172.  
  173. void GLAPIENTRY gluNurbsProperty( GLUnurbsObj *nobj, GLenum property, GLfloat value )
  174. {
  175.    GLenum val;
  176.  
  177.    switch (property) {
  178.       case GLU_SAMPLING_TOLERANCE:
  179.            if(value <= 0.0)
  180.            {
  181.                call_user_error(nobj,GLU_INVALID_VALUE);
  182.                return;
  183.          }
  184.          nobj->sampling_tolerance=value;
  185.          break;
  186.       case GLU_PARAMETRIC_TOLERANCE:
  187.            if(value <= 0.0)
  188.            {
  189.                call_user_error(nobj,GLU_INVALID_VALUE);
  190.                return;
  191.          }
  192.          nobj->parametric_tolerance=value;
  193.          break;
  194.       case GLU_U_STEP:
  195.            if(value <= 0.0)
  196.            {
  197.                call_user_error(nobj,GLU_INVALID_VALUE);
  198.                return;
  199.          }
  200.          nobj->u_step=(GLint)value;
  201.          break;
  202.       case GLU_V_STEP:
  203.            if(value <= 0.0)
  204.            {
  205.                call_user_error(nobj,GLU_INVALID_VALUE);
  206.                return;
  207.          }
  208.          nobj->v_step=(GLint)value;
  209.          break;
  210.       case GLU_SAMPLING_METHOD:
  211.          val = (GLenum)value;
  212.          if(val!=GLU_PATH_LENGTH && val!=GLU_PARAMETRIC_ERROR && val!=GLU_DOMAIN_DISTANCE)
  213.          {
  214.              call_user_error(nobj,GLU_INVALID_ENUM);
  215.              return;
  216.          }
  217.          nobj->sampling_method=val;
  218.          break;
  219.       case GLU_DISPLAY_MODE:
  220.          val=(GLenum)value;
  221.          if(val!=GLU_FILL && val!=GLU_OUTLINE_POLYGON && val!=GLU_OUTLINE_PATCH)
  222.          {
  223.              call_user_error(nobj,GLU_INVALID_ENUM);
  224.              return;
  225.          }
  226.          if(nobj->nurbs_type==GLU_NURBS_CURVE)
  227.          {
  228.              call_user_error(nobj,GLU_NURBS_ERROR26);
  229.              return;
  230.          }
  231.          nobj->display_mode=val;
  232. if(val==GLU_OUTLINE_PATCH)
  233.     fprintf(stderr,"NURBS, for the moment, can display only in POLYGON mode\n");
  234.          break;
  235.       case GLU_CULLING:
  236.          val=(GLenum)value;
  237.          if(val!=GL_TRUE && val!=GL_FALSE)
  238.          {
  239.              call_user_error(nobj,GLU_INVALID_ENUM);
  240.              return;
  241.          }
  242.          nobj->culling = (GLboolean) value;
  243.          break;
  244.       case GLU_AUTO_LOAD_MATRIX:
  245.          val=(GLenum)value;
  246.          if(val!=GL_TRUE && val!=GL_FALSE)
  247.          {
  248.              call_user_error(nobj,GLU_INVALID_ENUM);
  249.              return;
  250.          }
  251.          nobj->auto_load_matrix = (GLboolean) value;
  252.          break;
  253.       default:
  254.          call_user_error(nobj,GLU_NURBS_ERROR26);
  255.    }
  256. }
  257.  
  258.  
  259. void GLAPIENTRY gluGetNurbsProperty( GLUnurbsObj *nobj, GLenum property, GLfloat *value )
  260. {
  261.    switch (property) {
  262.       case GLU_SAMPLING_TOLERANCE:
  263.          *value = nobj->sampling_tolerance;
  264.          break;
  265.       case GLU_DISPLAY_MODE:
  266.          *value = (GLfloat) (GLint) nobj->display_mode;
  267.          break;
  268.       case GLU_CULLING:
  269.          *value = nobj->culling ? 1.0 : 0.0;
  270.          break;
  271.       case GLU_AUTO_LOAD_MATRIX:
  272.          *value = nobj->auto_load_matrix ? 1.0 : 0.0;
  273.          break;
  274.       default:
  275.          call_user_error(nobj,GLU_INVALID_ENUM);
  276.    }
  277. }
  278.  
  279.  
  280.  
  281. void GLAPIENTRY gluBeginCurve( GLUnurbsObj *nobj )
  282. {
  283.     if(nobj->nurbs_type==GLU_NURBS_CURVE)
  284.     {
  285.         call_user_error(nobj,GLU_NURBS_ERROR6);
  286.         return;
  287.     }
  288.     nobj->nurbs_type=GLU_NURBS_CURVE;
  289.     nobj->curve.geom.type=GLU_INVALID_ENUM;
  290.     nobj->curve.color.type=GLU_INVALID_ENUM;
  291.     nobj->curve.texture.type=GLU_INVALID_ENUM;
  292.     nobj->curve.normal.type=GLU_INVALID_ENUM;
  293. }
  294.  
  295.  
  296. void GLAPIENTRY gluEndCurve( GLUnurbsObj * nobj )
  297. {
  298.     if(nobj->nurbs_type==GLU_NURBS_NONE)
  299.     {
  300.         call_user_error(nobj,GLU_NURBS_ERROR7);
  301.         return;
  302.     }
  303.     if(nobj->curve.geom.type==GLU_INVALID_ENUM)
  304.     {
  305.         call_user_error(nobj,GLU_NURBS_ERROR8);
  306.         nobj->nurbs_type=GLU_NURBS_NONE;
  307.         return;
  308.     }
  309.     glPushAttrib( (GLbitfield) (GL_EVAL_BIT | GL_ENABLE_BIT) );
  310.     glDisable(GL_MAP1_VERTEX_3);
  311.     glDisable(GL_MAP1_VERTEX_4);
  312.     glDisable(GL_MAP1_INDEX);
  313.     glDisable(GL_MAP1_COLOR_4);
  314.     glDisable(GL_MAP1_NORMAL);
  315.     glDisable(GL_MAP1_TEXTURE_COORD_1);
  316.     glDisable(GL_MAP1_TEXTURE_COORD_2);
  317.     glDisable(GL_MAP1_TEXTURE_COORD_3);
  318.     glDisable(GL_MAP1_TEXTURE_COORD_4);
  319.     glDisable(GL_MAP2_VERTEX_3);
  320.     glDisable(GL_MAP2_VERTEX_4);
  321.     glDisable(GL_MAP2_INDEX);
  322.     glDisable(GL_MAP2_COLOR_4);
  323.     glDisable(GL_MAP2_NORMAL);
  324.     glDisable(GL_MAP2_TEXTURE_COORD_1);
  325.     glDisable(GL_MAP2_TEXTURE_COORD_2);
  326.     glDisable(GL_MAP2_TEXTURE_COORD_3);
  327.     glDisable(GL_MAP2_TEXTURE_COORD_4);
  328.     do_nurbs_curve(nobj);
  329.     glPopAttrib();
  330.     nobj->nurbs_type=GLU_NURBS_NONE;
  331. }
  332.  
  333.  
  334. void GLAPIENTRY gluNurbsCurve( GLUnurbsObj *nobj, GLint nknots, GLfloat *knot,
  335.             GLint stride, GLfloat *ctlarray, GLint order, GLenum type )
  336. {
  337.     if(nobj->nurbs_type==GLU_NURBS_TRIM)
  338.     {
  339. #if 0
  340. /* TODO: NOT IMPLEMENTED YET */
  341.         nurbs_trim *ptr1;
  342.         trim_list *ptr2;
  343.  
  344.         if(type!=GLU_MAP1_TRIM_2 && type!=GLU_MAP1_TRIM_3)
  345.         {
  346.             call_user_error(nobj,GLU_NURBS_ERROR14);
  347.             return;
  348.         }
  349.         for(ptr1=nobj->trim;ptr1->next;ptr1=ptr1->next);
  350.         if(ptr1->trim_loop)
  351.         {
  352.             for(ptr2=ptr1->trim_loop;ptr2->next;ptr2=ptr2->next);
  353.             if((ptr2->next=(trim_list *)malloc(sizeof(trim_list)))==NULL)
  354.             {
  355.                 call_user_error(nobj,GLU_OUT_OF_MEMORY);
  356.                 return;
  357.             }
  358.             ptr2=ptr2->next;
  359.         }
  360.         else
  361.         {
  362.             if((ptr2=(trim_list *)malloc(sizeof(trim_list)))==NULL)
  363.             {
  364.                 call_user_error(nobj,GLU_OUT_OF_MEMORY);
  365.                 return;
  366.             }
  367.             ptr1->trim_loop=ptr2;
  368.         }
  369.         ptr2->trim_type=GLU_TRIM_NURBS;
  370.         ptr2->curve.nurbs_curve.knot_count=nknots;
  371.         ptr2->curve.nurbs_curve.knot=knot;
  372.         ptr2->curve.nurbs_curve.stride=stride;
  373.         ptr2->curve.nurbs_curve.ctrlarray=ctlarray;
  374.         ptr2->curve.nurbs_curve.order=order;
  375.         ptr2->curve.nurbs_curve.dim= (type==GLU_MAP1_TRIM_2 ? 2 : 3 );
  376.         ptr2->curve.nurbs_curve.type=type;
  377.         ptr2->next=NULL;
  378. #endif
  379.     }
  380.     else
  381.     {
  382.         if(type==GLU_MAP1_TRIM_2 || type==GLU_MAP1_TRIM_3)
  383.         {
  384.             call_user_error(nobj,GLU_NURBS_ERROR22);
  385.             return;
  386.         }
  387.         if(nobj->nurbs_type!=GLU_NURBS_CURVE)
  388.         {
  389.             call_user_error(nobj,GLU_NURBS_ERROR10);
  390.             return;
  391.         }
  392.         switch(type)
  393.         {
  394.             case GL_MAP1_VERTEX_3:
  395.             case GL_MAP1_VERTEX_4:
  396.                 if(nobj->curve.geom.type!=GLU_INVALID_ENUM)
  397.                 {
  398.                     call_user_error(nobj,GLU_NURBS_ERROR8);
  399.                     return;
  400.                 }
  401.                 nobj->curve.geom.type=type;
  402.                 nobj->curve.geom.knot_count=nknots;
  403.                 nobj->curve.geom.knot=knot;
  404.                 nobj->curve.geom.stride=stride;
  405.                 nobj->curve.geom.ctrlarray=ctlarray;
  406.                 nobj->curve.geom.order=order;
  407.                 break;
  408.             case GL_MAP1_INDEX:
  409.             case GL_MAP1_COLOR_4:
  410.                 nobj->curve.color.type=type;
  411.                 nobj->curve.color.knot_count=nknots;
  412.                 nobj->curve.color.knot=knot;
  413.                 nobj->curve.color.stride=stride;
  414.                 nobj->curve.color.ctrlarray=ctlarray;
  415.                 nobj->curve.color.order=order;
  416.                 break;
  417.             case GL_MAP1_NORMAL:
  418.                 nobj->curve.normal.type=type;
  419.                 nobj->curve.normal.knot_count=nknots;
  420.                 nobj->curve.normal.knot=knot;
  421.                 nobj->curve.normal.stride=stride;
  422.                 nobj->curve.normal.ctrlarray=ctlarray;
  423.                 nobj->curve.normal.order=order;
  424.                 break;
  425.             case GL_MAP1_TEXTURE_COORD_1:
  426.             case GL_MAP1_TEXTURE_COORD_2:
  427.             case GL_MAP1_TEXTURE_COORD_3:
  428.             case GL_MAP1_TEXTURE_COORD_4:
  429.                 nobj->curve.texture.type=type;
  430.                 nobj->curve.texture.knot_count=nknots;
  431.                 nobj->curve.texture.knot=knot;
  432.                 nobj->curve.texture.stride=stride;
  433.                 nobj->curve.texture.ctrlarray=ctlarray;
  434.                 nobj->curve.texture.order=order;
  435.                 break;
  436.             default:
  437.                  call_user_error(nobj,GLU_INVALID_ENUM);
  438.         }
  439.     }
  440. }
  441.  
  442.  
  443. void GLAPIENTRY gluBeginSurface( GLUnurbsObj *nobj )
  444. {
  445.     switch(nobj->nurbs_type)
  446.     {
  447.         case GLU_NURBS_NONE:
  448.             nobj->nurbs_type=GLU_NURBS_SURFACE;
  449.             nobj->surface.geom.type=GLU_INVALID_ENUM;
  450.             nobj->surface.color.type=GLU_INVALID_ENUM;
  451.             nobj->surface.texture.type=GLU_INVALID_ENUM;
  452.             nobj->surface.normal.type=GLU_INVALID_ENUM;
  453.             break;
  454.         case GLU_NURBS_TRIM:
  455.             call_user_error(nobj,GLU_NURBS_ERROR16);
  456.             break;
  457.         case GLU_NURBS_SURFACE:
  458.         case GLU_NURBS_NO_TRIM:
  459.         case GLU_NURBS_TRIM_DONE:
  460.             call_user_error(nobj,GLU_NURBS_ERROR27);
  461.             break;
  462.         case GLU_NURBS_CURVE:
  463.             call_user_error(nobj,GLU_NURBS_ERROR6);
  464.             break;
  465.     }
  466. }
  467.  
  468.  
  469. void GLAPIENTRY gluEndSurface( GLUnurbsObj * nobj )
  470. {
  471.     switch(nobj->nurbs_type)
  472.     {
  473.         case GLU_NURBS_NONE:
  474.             call_user_error(nobj,GLU_NURBS_ERROR13);
  475.             break;
  476.         case GLU_NURBS_TRIM:
  477.             call_user_error(nobj,GLU_NURBS_ERROR12);
  478.             break;
  479.         case GLU_NURBS_TRIM_DONE:
  480. /*            if(nobj->trim->trim_loop==NULL)
  481.             {
  482.                 call_user_error(nobj,GLU_NURBS_ERROR18);
  483.                 return;
  484.             }*/
  485.             /* no break - fallthrough */
  486.         case GLU_NURBS_NO_TRIM:
  487.             glPushAttrib( (GLbitfield)
  488.                 (GL_EVAL_BIT | GL_ENABLE_BIT | GL_POLYGON_BIT) );
  489.             glDisable(GL_MAP2_VERTEX_3);
  490.             glDisable(GL_MAP2_VERTEX_4);
  491.             glDisable(GL_MAP2_INDEX);
  492.             glDisable(GL_MAP2_COLOR_4);
  493.             glDisable(GL_MAP2_NORMAL);
  494.             glDisable(GL_MAP2_TEXTURE_COORD_1);
  495.             glDisable(GL_MAP2_TEXTURE_COORD_2);
  496.             glDisable(GL_MAP2_TEXTURE_COORD_3);
  497.             glDisable(GL_MAP2_TEXTURE_COORD_4);
  498. /*            glDisable(GL_MAP1_VERTEX_3);
  499.             glDisable(GL_MAP1_VERTEX_4);
  500.             glDisable(GL_MAP1_INDEX);
  501.             glDisable(GL_MAP1_COLOR_4);
  502.             glDisable(GL_MAP1_NORMAL);
  503.             glDisable(GL_MAP1_TEXTURE_COORD_1);
  504.             glDisable(GL_MAP1_TEXTURE_COORD_2);
  505.             glDisable(GL_MAP1_TEXTURE_COORD_3);
  506.             glDisable(GL_MAP1_TEXTURE_COORD_4);*/
  507.             do_nurbs_surface(nobj);
  508.             glPopAttrib();
  509.             break;
  510.         default:
  511.             call_user_error(nobj,GLU_NURBS_ERROR8);
  512.     }
  513.     nobj->nurbs_type=GLU_NURBS_NONE;
  514. }
  515.  
  516.  
  517. void GLAPIENTRY gluNurbsSurface( GLUnurbsObj *nobj,
  518.               GLint sknot_count, GLfloat *sknot,
  519.               GLint tknot_count, GLfloat *tknot,
  520.               GLint s_stride, GLint t_stride,
  521.               GLfloat *ctrlarray,
  522.               GLint sorder, GLint torder,
  523.               GLenum type )
  524. {
  525.     if(nobj->nurbs_type==GLU_NURBS_NO_TRIM || nobj->nurbs_type==GLU_NURBS_TRIM ||
  526.         nobj->nurbs_type==GLU_NURBS_TRIM_DONE)
  527.     {
  528.         if(type==GL_MAP2_VERTEX_3 || type==GL_MAP2_VERTEX_4)
  529.         {
  530.             call_user_error(nobj,GLU_NURBS_ERROR8);
  531.             return;
  532.         }
  533.     }
  534.     else
  535.     if(nobj->nurbs_type!=GLU_NURBS_SURFACE)
  536.     {
  537.         call_user_error(nobj,GLU_NURBS_ERROR11);
  538.         return;
  539.     }
  540.     switch(type)
  541.     {
  542.         case GL_MAP2_VERTEX_3:
  543.         case GL_MAP2_VERTEX_4:
  544.             nobj->surface.geom.sknot_count=sknot_count;
  545.             nobj->surface.geom.sknot=sknot;
  546.             nobj->surface.geom.tknot_count=tknot_count;
  547.             nobj->surface.geom.tknot=tknot;
  548.             nobj->surface.geom.s_stride=s_stride;
  549.             nobj->surface.geom.t_stride=t_stride;
  550.             nobj->surface.geom.ctrlarray=ctrlarray;
  551.             nobj->surface.geom.sorder=sorder;
  552.             nobj->surface.geom.torder=torder;
  553.             nobj->surface.geom.type=type;
  554.             nobj->nurbs_type=GLU_NURBS_NO_TRIM;
  555.             break;
  556.         case GL_MAP2_INDEX:
  557.         case GL_MAP2_COLOR_4:
  558.             nobj->surface.color.sknot_count=sknot_count;
  559.             nobj->surface.color.sknot=sknot;
  560.             nobj->surface.color.tknot_count=tknot_count;
  561.             nobj->surface.color.tknot=tknot;
  562.             nobj->surface.color.s_stride=s_stride;
  563.             nobj->surface.color.t_stride=t_stride;
  564.             nobj->surface.color.ctrlarray=ctrlarray;
  565.             nobj->surface.color.sorder=sorder;
  566.             nobj->surface.color.torder=torder;
  567.             nobj->surface.color.type=type;
  568.             break;
  569.         case GL_MAP2_NORMAL:
  570.             nobj->surface.normal.sknot_count=sknot_count;
  571.             nobj->surface.normal.sknot=sknot;
  572.             nobj->surface.normal.tknot_count=tknot_count;
  573.             nobj->surface.normal.tknot=tknot;
  574.             nobj->surface.normal.s_stride=s_stride;
  575.             nobj->surface.normal.t_stride=t_stride;
  576.             nobj->surface.normal.ctrlarray=ctrlarray;
  577.             nobj->surface.normal.sorder=sorder;
  578.             nobj->surface.normal.torder=torder;
  579.             nobj->surface.normal.type=type;
  580.             break;
  581.         case GL_MAP2_TEXTURE_COORD_1:
  582.         case GL_MAP2_TEXTURE_COORD_2:
  583.         case GL_MAP2_TEXTURE_COORD_3:
  584.         case GL_MAP2_TEXTURE_COORD_4:
  585.             nobj->surface.texture.sknot_count=sknot_count;
  586.             nobj->surface.texture.sknot=sknot;
  587.             nobj->surface.texture.tknot_count=tknot_count;
  588.             nobj->surface.texture.tknot=tknot;
  589.             nobj->surface.texture.s_stride=s_stride;
  590.             nobj->surface.texture.t_stride=t_stride;
  591.             nobj->surface.texture.ctrlarray=ctrlarray;
  592.             nobj->surface.texture.sorder=sorder;
  593.             nobj->surface.texture.torder=torder;
  594.             nobj->surface.texture.type=type;
  595.             break;
  596.         default:
  597.              call_user_error(nobj,GLU_INVALID_ENUM);
  598.     }
  599. }
  600.  
  601.  
  602. void GLAPIENTRY
  603. gluNurbsCallback( GLUnurbsObj *nobj, GLenum which, void (GLCALLBACK *fn)())
  604. {
  605. #if defined(__CYGWIN32__) || defined(OPENSTEP)
  606.     nobj->error_callback = (void(*)(GLenum))fn;
  607. #else
  608.     nobj->error_callback = (void(GLCALLBACK*)(GLenum))fn;
  609. #endif
  610.  
  611.     if(which!=GLU_ERROR)
  612.         call_user_error(nobj,GLU_INVALID_ENUM);
  613. }
  614.  
  615. void GLAPIENTRY
  616. gluBeginTrim( GLUnurbsObj *nobj )
  617. {
  618. #if 0
  619.     nurbs_trim *ptr;
  620. #endif
  621.  
  622.     if(nobj->nurbs_type!=GLU_NURBS_TRIM_DONE)
  623.         if(nobj->nurbs_type!=GLU_NURBS_NO_TRIM)
  624.         {
  625.             call_user_error(nobj,GLU_NURBS_ERROR15);
  626.             return;
  627.         }
  628.     nobj->nurbs_type=GLU_NURBS_TRIM;
  629. fprintf(stderr,"NURBS - trimming not supported yet\n");
  630. #if 0
  631.     if((ptr=(nurbs_trim *)malloc(sizeof(nurbs_trim)))==NULL)
  632.     {
  633.         call_user_error(nobj,GLU_OUT_OF_MEMORY);
  634.         return;
  635.     }
  636.     if(nobj->trim)
  637.     {
  638.         nurbs_trim *tmp_ptr;
  639.  
  640.         for(tmp_ptr=nobj->trim;tmp_ptr->next;tmp_ptr=tmp_ptr->next);
  641.         tmp_ptr->next=ptr;
  642.     }
  643.     else
  644.         nobj->trim=ptr;
  645.     ptr->trim_loop=NULL;
  646.     ptr->segments=NULL;
  647.     ptr->next=NULL;
  648. #endif
  649. }
  650.  
  651. void GLAPIENTRY
  652. gluPwlCurve( GLUnurbsObj *nobj, GLint count, GLfloat *array, GLint stride,
  653.     GLenum type)
  654. {
  655. #if 0
  656.     nurbs_trim *ptr1;
  657.     trim_list *ptr2;
  658. #endif
  659.     if(nobj->nurbs_type==GLU_NURBS_CURVE)
  660.     {
  661.         call_user_error(nobj,GLU_NURBS_ERROR9);
  662.         return;
  663.     }
  664.     if(nobj->nurbs_type==GLU_NURBS_NONE)
  665.     {
  666.         call_user_error(nobj,GLU_NURBS_ERROR19);
  667.         return;
  668.     }
  669.     if(type!=GLU_MAP1_TRIM_2 && type!=GLU_MAP1_TRIM_3)
  670.     {
  671.         call_user_error(nobj,GLU_NURBS_ERROR14);
  672.         return;
  673.     }
  674. #if 0
  675.     for(ptr1=nobj->trim;ptr1->next;ptr1=ptr1->next);
  676.     if(ptr1->trim_loop)
  677.     {
  678.         for(ptr2=ptr1->trim_loop;ptr2->next;ptr2=ptr2->next);
  679.         if((ptr2->next=(trim_list *)malloc(sizeof(trim_list)))==NULL)
  680.         {
  681.             call_user_error(nobj,GLU_OUT_OF_MEMORY);
  682.             return;
  683.         }
  684.         ptr2=ptr2->next;
  685.     }
  686.     else
  687.     {
  688.         if((ptr2=(trim_list *)malloc(sizeof(trim_list)))==NULL)
  689.         {
  690.             call_user_error(nobj,GLU_OUT_OF_MEMORY);
  691.             return;
  692.         }
  693.         ptr1->trim_loop=ptr2;
  694.     }
  695.     ptr2->trim_type=GLU_TRIM_PWL;
  696.     ptr2->curve.pwl_curve.pt_count=count;
  697.     ptr2->curve.pwl_curve.ctrlarray=array;
  698.     ptr2->curve.pwl_curve.stride=stride;
  699.     ptr2->curve.pwl_curve.dim= (type==GLU_MAP1_TRIM_2 ? 2 : 3 );
  700.     ptr2->curve.pwl_curve.type=type;
  701.     ptr2->next=NULL;
  702. #endif
  703. }
  704.  
  705. void GLAPIENTRY
  706. gluEndTrim( GLUnurbsObj *nobj )
  707. {
  708.     if(nobj->nurbs_type!=GLU_NURBS_TRIM)
  709.     {
  710.         call_user_error(nobj,GLU_NURBS_ERROR17);
  711.         return;
  712.     }
  713.     nobj->nurbs_type=GLU_NURBS_TRIM_DONE;
  714. }
  715.  
  716.