home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / mesa-1.2.8 / src-glu / nurbs.c < prev    next >
C/C++ Source or Header  |  1996-05-27  |  17KB  |  666 lines

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