home *** CD-ROM | disk | FTP | other *** search
/ Amiga Magazin: Amiga-CD 2000 April & May / AMIGA_2000_04.iso / patches / mesa3.1 / samples / nurb.c < prev    next >
C/C++ Source or Header  |  2000-01-01  |  6KB  |  356 lines

  1. /*
  2.  * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name of
  8.  * Silicon Graphics may not be used in any advertising or
  9.  * publicity relating to the software without the specific, prior written
  10.  * permission of Silicon Graphics.
  11.  *
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
  13.  * ANY KIND,
  14.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  15.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  16.  *
  17.  * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
  18.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  19.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
  21.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  22.  * OF THIS SOFTWARE.
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <math.h>
  29. #include <GL/glut.h>
  30.  
  31.  
  32. #ifndef CALLBACK
  33. #define CALLBACK
  34. #endif
  35.  
  36.  
  37. #define INREAL float
  38.  
  39. #define S_NUMPOINTS 13
  40. #define S_ORDER     3   
  41. #define S_NUMKNOTS  (S_NUMPOINTS + S_ORDER)
  42. #define T_NUMPOINTS 3
  43. #define T_ORDER     3 
  44. #define T_NUMKNOTS  (T_NUMPOINTS + T_ORDER)
  45. #define SQRT_TWO    1.41421356237309504880
  46.  
  47.  
  48. typedef INREAL Point[4];
  49.  
  50.  
  51. GLenum doubleBuffer;
  52.  
  53. GLenum expectedError;
  54. GLint rotX = 40, rotY = 40;
  55. INREAL sknots[S_NUMKNOTS] = {
  56.     -1.0, -1.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0,
  57.     4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 9.0, 9.0
  58. };
  59. INREAL tknots[T_NUMKNOTS] = {
  60.     1.0, 1.0, 1.0, 2.0, 2.0, 2.0
  61. };
  62. Point ctlpoints[S_NUMPOINTS][T_NUMPOINTS] = {
  63.     {
  64.     {
  65.         4.0, 2.0, 2.0, 1.0
  66.     },
  67.     {
  68.         4.0, 1.6, 2.5, 1.0
  69.     },
  70.     {
  71.         4.0, 2.0, 3.0, 1.0
  72.     }
  73.     },
  74.     {
  75.     {
  76.         5.0, 4.0, 2.0, 1.0
  77.     },
  78.     {
  79.         5.0, 4.0, 2.5, 1.0
  80.     },
  81.     {
  82.         5.0, 4.0, 3.0, 1.0
  83.     }
  84.     },
  85.     {
  86.     {
  87.         6.0, 5.0, 2.0, 1.0
  88.     },
  89.     {
  90.         6.0, 5.0, 2.5, 1.0
  91.     },
  92.     {
  93.         6.0, 5.0, 3.0, 1.0
  94.     }
  95.     },
  96.     {
  97.     {
  98.         SQRT_TWO*6.0, SQRT_TWO*6.0, SQRT_TWO*2.0, SQRT_TWO
  99.     },
  100.     {
  101.         SQRT_TWO*6.0, SQRT_TWO*6.0, SQRT_TWO*2.5, SQRT_TWO
  102.     },
  103.     {
  104.         SQRT_TWO*6.0, SQRT_TWO*6.0, SQRT_TWO*3.0, SQRT_TWO
  105.     }  
  106.     },
  107.     {
  108.     {
  109.         5.2, 6.7, 2.0, 1.0
  110.     },
  111.     {
  112.         5.2, 6.7, 2.5, 1.0
  113.     },
  114.     {
  115.         5.2, 6.7, 3.0, 1.0
  116.     }
  117.     },
  118.     {
  119.     {
  120.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*2.0, SQRT_TWO
  121.     },
  122.     {
  123.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*2.5, SQRT_TWO
  124.     }, 
  125.     {
  126.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*3.0, SQRT_TWO
  127.     }  
  128.     }, 
  129.     {
  130.     {
  131.         4.0, 5.2, 2.0, 1.0
  132.     },
  133.     {
  134.         4.0, 4.6, 2.5, 1.0
  135.     },
  136.     {
  137.         4.0, 5.2, 3.0, 1.0
  138.     }  
  139.     },
  140.     {
  141.     {
  142.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*2.0, SQRT_TWO
  143.     },
  144.     {
  145.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*2.5, SQRT_TWO
  146.     },
  147.     {
  148.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*3.0, SQRT_TWO
  149.     }  
  150.     },
  151.     {
  152.     {
  153.         2.8, 6.7, 2.0, 1.0
  154.     },
  155.     {
  156.         2.8, 6.7, 2.5, 1.0
  157.     },
  158.     {
  159.         2.8, 6.7, 3.0, 1.0
  160.     }   
  161.     },
  162.     {
  163.     {
  164.         SQRT_TWO*2.0, SQRT_TWO*6.0, SQRT_TWO*2.0, SQRT_TWO
  165.     },
  166.     {
  167.         SQRT_TWO*2.0, SQRT_TWO*6.0, SQRT_TWO*2.5, SQRT_TWO
  168.     },
  169.     {
  170.         SQRT_TWO*2.0, SQRT_TWO*6.0, SQRT_TWO*3.0, SQRT_TWO
  171.     }  
  172.     },
  173.     {
  174.     {
  175.         2.0, 5.0, 2.0, 1.0
  176.     },
  177.     {
  178.         2.0, 5.0, 2.5, 1.0
  179.     },
  180.     {
  181.         2.0, 5.0, 3.0, 1.0
  182.     } 
  183.     },
  184.     {
  185.     {
  186.         3.0, 4.0, 2.0, 1.0
  187.     },
  188.     {
  189.         3.0, 4.0, 2.5, 1.0
  190.     },
  191.     {
  192.         3.0, 4.0, 3.0, 1.0
  193.     } 
  194.     },
  195.     {
  196.     {
  197.         4.0, 2.0, 2.0, 1.0
  198.     },
  199.     {
  200.         4.0, 1.6, 2.5, 1.0
  201.     },
  202.     {
  203.         4.0, 2.0, 3.0, 1.0
  204.     }    
  205.     }
  206. };
  207. GLUnurbsObj *theNurbs;
  208.  
  209.  
  210. static void CALLBACK ErrorCallback(GLenum which)
  211. {
  212.  
  213.     if (which != expectedError) {
  214.     fprintf(stderr, "Unexpected error occured (%d):\n", which);
  215.     fprintf(stderr, "    %s\n", (char *) gluErrorString(which));
  216.     }
  217. }
  218.  
  219. static void Init(void)
  220. {
  221.  
  222.     theNurbs = gluNewNurbsRenderer();
  223.     gluNurbsCallback(theNurbs, GLU_ERROR, ErrorCallback);
  224.  
  225.     gluNurbsProperty(theNurbs, GLU_SAMPLING_TOLERANCE, 15.0);
  226.     gluNurbsProperty(theNurbs, GLU_DISPLAY_MODE, GLU_OUTLINE_PATCH);
  227.  
  228.     expectedError = GLU_INVALID_ENUM;
  229.     gluNurbsProperty(theNurbs, ~0, 15.0);
  230.     expectedError = GLU_NURBS_ERROR13;
  231.     gluEndSurface(theNurbs);
  232.     expectedError = 0;
  233.  
  234.     glColor3f(1.0, 1.0, 1.0);
  235. }
  236.  
  237. static void Reshape(int width, int height)
  238. {
  239.  
  240.     glViewport(0, 0, (GLint)width, (GLint)height);
  241.  
  242.     glMatrixMode(GL_PROJECTION);
  243.     glLoadIdentity();
  244.     glFrustum(-2.0, 2.0, -2.0, 2.0, 0.8, 10.0);
  245.     gluLookAt(7.0, 4.5, 4.0, 4.5, 4.5, 2.5, 6.0, -3.0, 2.0);
  246.     glMatrixMode(GL_MODELVIEW);
  247. }
  248.  
  249. static void Key2(int key, int x, int y)
  250. {
  251.  
  252.     switch (key) {
  253.       case GLUT_KEY_DOWN:
  254.     rotX -= 5;
  255.     break;
  256.       case GLUT_KEY_UP:
  257.     rotX += 5;
  258.     break;
  259.       case GLUT_KEY_LEFT:
  260.     rotY -= 5;
  261.     break;
  262.       case GLUT_KEY_RIGHT:
  263.     rotY += 5;
  264.     break;
  265.       default:
  266.     return;
  267.     }
  268.  
  269.     glutPostRedisplay();
  270. }
  271.  
  272. static void Key(unsigned char key, int x, int y)
  273. {
  274.  
  275.     switch (key) {
  276.       case 27:
  277.     exit(1);
  278.     }
  279. }
  280.  
  281. static void Draw(void)
  282. {
  283.  
  284.     glClear(GL_COLOR_BUFFER_BIT);
  285.  
  286.     glPushMatrix();
  287.  
  288.     glTranslatef(4.0, 4.5, 2.5);
  289.     glRotatef(rotY, 1, 0, 0);
  290.     glRotatef(rotX, 0, 1, 0);
  291.     glTranslatef(-4.0, -4.5, -2.5);
  292.  
  293.     gluBeginSurface(theNurbs);
  294.     gluNurbsSurface(theNurbs, S_NUMKNOTS, sknots, T_NUMKNOTS, tknots,
  295.             4*T_NUMPOINTS, 4, &ctlpoints[0][0][0], S_ORDER,
  296.             T_ORDER, GL_MAP2_VERTEX_4);
  297.     gluEndSurface(theNurbs);
  298.  
  299.     glPopMatrix();
  300.  
  301.     glFlush();
  302.  
  303.     if (doubleBuffer) {
  304.     glutSwapBuffers();
  305.     }
  306. }
  307.  
  308. static GLenum Args(int argc, char **argv)
  309. {
  310.     GLint i;
  311.  
  312.     doubleBuffer = GL_FALSE;
  313.  
  314.     for (i = 1; i < argc; i++) {
  315.     if (strcmp(argv[i], "-sb") == 0) {
  316.         doubleBuffer = GL_FALSE;
  317.     } else if (strcmp(argv[i], "-db") == 0) {
  318.         doubleBuffer = GL_TRUE;
  319.     } else {
  320.         printf("%s (Bad option).\n", argv[i]);
  321.         return GL_FALSE;
  322.     }
  323.     }
  324.     return GL_TRUE;
  325. }
  326.  
  327. int main(int argc, char **argv)
  328. {
  329.     GLenum type;
  330.  
  331.     glutInit(&argc, argv);
  332.  
  333.     if (Args(argc, argv) == GL_FALSE) {
  334.     exit(1);
  335.     }
  336.  
  337.     glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
  338.  
  339.     type = GLUT_RGB;
  340.     type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
  341.     glutInitDisplayMode(type);
  342.  
  343.     if (glutCreateWindow("NURBS Test") == GL_FALSE) {
  344.     exit(1);
  345.     }
  346.  
  347.     Init();
  348.  
  349.     glutReshapeFunc(Reshape);
  350.     glutKeyboardFunc(Key);
  351.     glutSpecialFunc(Key2);
  352.     glutDisplayFunc(Draw);
  353.     glutMainLoop();
  354.     return 0;
  355. }
  356.