home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / mesa-1.2.8 / samples / nurb.c < prev    next >
C/C++ Source or Header  |  1996-05-27  |  6KB  |  348 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 <GL/gl.h>
  29. #include <GL/glu.h>
  30. #include <math.h>
  31. #include "gltk.h"
  32.  
  33.  
  34. #define INREAL float
  35.  
  36. #define S_NUMPOINTS 13
  37. #define S_ORDER     3   
  38. #define S_NUMKNOTS  (S_NUMPOINTS + S_ORDER)
  39. #define T_NUMPOINTS 3
  40. #define T_ORDER     3 
  41. #define T_NUMKNOTS  (T_NUMPOINTS + T_ORDER)
  42. #define SQRT_TWO    1.41421356237309504880
  43.  
  44.  
  45. typedef INREAL Point[4];
  46.  
  47.  
  48. GLenum doubleBuffer, directRender;
  49.  
  50. GLenum expectedError;
  51. GLint rotX = 40, rotY = 40;
  52. INREAL sknots[S_NUMKNOTS] = {
  53.     -1.0, -1.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0,
  54.     4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 9.0, 9.0
  55. };
  56. INREAL tknots[T_NUMKNOTS] = {
  57.     1.0, 1.0, 1.0, 2.0, 2.0, 2.0
  58. };
  59. Point ctlpoints[S_NUMPOINTS][T_NUMPOINTS] = {
  60.     {
  61.     {
  62.         4.0, 2.0, 2.0, 1.0
  63.     },
  64.     {
  65.         4.0, 1.6, 2.5, 1.0
  66.     },
  67.     {
  68.         4.0, 2.0, 3.0, 1.0
  69.     }
  70.     },
  71.     {
  72.     {
  73.         5.0, 4.0, 2.0, 1.0
  74.     },
  75.     {
  76.         5.0, 4.0, 2.5, 1.0
  77.     },
  78.     {
  79.         5.0, 4.0, 3.0, 1.0
  80.     }
  81.     },
  82.     {
  83.     {
  84.         6.0, 5.0, 2.0, 1.0
  85.     },
  86.     {
  87.         6.0, 5.0, 2.5, 1.0
  88.     },
  89.     {
  90.         6.0, 5.0, 3.0, 1.0
  91.     }
  92.     },
  93.     {
  94.     {
  95.         SQRT_TWO*6.0, SQRT_TWO*6.0, SQRT_TWO*2.0, SQRT_TWO
  96.     },
  97.     {
  98.         SQRT_TWO*6.0, SQRT_TWO*6.0, SQRT_TWO*2.5, SQRT_TWO
  99.     },
  100.     {
  101.         SQRT_TWO*6.0, SQRT_TWO*6.0, SQRT_TWO*3.0, SQRT_TWO
  102.     }  
  103.     },
  104.     {
  105.     {
  106.         5.2, 6.7, 2.0, 1.0
  107.     },
  108.     {
  109.         5.2, 6.7, 2.5, 1.0
  110.     },
  111.     {
  112.         5.2, 6.7, 3.0, 1.0
  113.     }
  114.     },
  115.     {
  116.     {
  117.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*2.0, SQRT_TWO
  118.     },
  119.     {
  120.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*2.5, SQRT_TWO
  121.     }, 
  122.     {
  123.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*3.0, SQRT_TWO
  124.     }  
  125.     }, 
  126.     {
  127.     {
  128.         4.0, 5.2, 2.0, 1.0
  129.     },
  130.     {
  131.         4.0, 4.6, 2.5, 1.0
  132.     },
  133.     {
  134.         4.0, 5.2, 3.0, 1.0
  135.     }  
  136.     },
  137.     {
  138.     {
  139.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*2.0, SQRT_TWO
  140.     },
  141.     {
  142.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*2.5, SQRT_TWO
  143.     },
  144.     {
  145.         SQRT_TWO*4.0, SQRT_TWO*6.0, SQRT_TWO*3.0, SQRT_TWO
  146.     }  
  147.     },
  148.     {
  149.     {
  150.         2.8, 6.7, 2.0, 1.0
  151.     },
  152.     {
  153.         2.8, 6.7, 2.5, 1.0
  154.     },
  155.     {
  156.         2.8, 6.7, 3.0, 1.0
  157.     }   
  158.     },
  159.     {
  160.     {
  161.         SQRT_TWO*2.0, SQRT_TWO*6.0, SQRT_TWO*2.0, SQRT_TWO
  162.     },
  163.     {
  164.         SQRT_TWO*2.0, SQRT_TWO*6.0, SQRT_TWO*2.5, SQRT_TWO
  165.     },
  166.     {
  167.         SQRT_TWO*2.0, SQRT_TWO*6.0, SQRT_TWO*3.0, SQRT_TWO
  168.     }  
  169.     },
  170.     {
  171.     {
  172.         2.0, 5.0, 2.0, 1.0
  173.     },
  174.     {
  175.         2.0, 5.0, 2.5, 1.0
  176.     },
  177.     {
  178.         2.0, 5.0, 3.0, 1.0
  179.     } 
  180.     },
  181.     {
  182.     {
  183.         3.0, 4.0, 2.0, 1.0
  184.     },
  185.     {
  186.         3.0, 4.0, 2.5, 1.0
  187.     },
  188.     {
  189.         3.0, 4.0, 3.0, 1.0
  190.     } 
  191.     },
  192.     {
  193.     {
  194.         4.0, 2.0, 2.0, 1.0
  195.     },
  196.     {
  197.         4.0, 1.6, 2.5, 1.0
  198.     },
  199.     {
  200.         4.0, 2.0, 3.0, 1.0
  201.     }    
  202.     }
  203. };
  204. GLUnurbsObj *theNurbs;
  205.  
  206.  
  207. static void ErrorCallback(GLenum which)
  208. {
  209.  
  210.     if (which != expectedError) {
  211.     fprintf(stderr, "Unexpected error occured (%d):\n", which);
  212.     fprintf(stderr, "    %s\n", gluErrorString(which));
  213.     }
  214. }
  215.  
  216. static void Init(void)
  217. {
  218.  
  219.     theNurbs = gluNewNurbsRenderer();
  220.     gluNurbsCallback(theNurbs, GLU_ERROR, ErrorCallback);
  221.  
  222.     gluNurbsProperty(theNurbs, GLU_SAMPLING_TOLERANCE, 15.0);
  223.     gluNurbsProperty(theNurbs, GLU_DISPLAY_MODE, GLU_OUTLINE_PATCH);
  224.  
  225.     expectedError = GLU_INVALID_ENUM;
  226.     gluNurbsProperty(theNurbs, ~0, 15.0);
  227.     expectedError = GLU_NURBS_ERROR13;
  228.     gluEndSurface(theNurbs);
  229.     expectedError = 0;
  230.  
  231.     glColor3f(1.0, 1.0, 1.0);
  232. }
  233.  
  234. static void Reshape(int width, int height)
  235. {
  236.  
  237.     glViewport(0, 0, (GLint)width, (GLint)height);
  238.  
  239.     glMatrixMode(GL_PROJECTION);
  240.     glLoadIdentity();
  241.     glFrustum(-2.0, 2.0, -2.0, 2.0, 0.8, 10.0);
  242.     gluLookAt(7.0, 4.5, 4.0, 4.5, 4.5, 2.5, 6.0, -3.0, 2.0);
  243.     glMatrixMode(GL_MODELVIEW);
  244. }
  245.  
  246. static GLenum Key(int key, GLenum mask)
  247. {
  248.  
  249.     switch (key) {
  250.       case TK_ESCAPE:
  251.     tkQuit();
  252.       case TK_DOWN:
  253.     rotX -= 5;
  254.     break;
  255.       case TK_UP:
  256.     rotX += 5;
  257.     break;
  258.       case TK_LEFT:
  259.     rotY -= 5;
  260.     break;
  261.       case TK_RIGHT:
  262.     rotY += 5;
  263.     break;
  264.       default:
  265.     return GL_FALSE;
  266.     }
  267.     return GL_TRUE;
  268. }
  269.  
  270. static void Draw(void)
  271. {
  272.  
  273.     glClear(GL_COLOR_BUFFER_BIT);
  274.  
  275.     glPushMatrix();
  276.  
  277.     glTranslatef(4.0, 4.5, 2.5);
  278.     glRotatef(rotY, 1, 0, 0);
  279.     glRotatef(rotX, 0, 1, 0);
  280.     glTranslatef(-4.0, -4.5, -2.5);
  281.  
  282.     gluBeginSurface(theNurbs);
  283.     gluNurbsSurface(theNurbs, S_NUMKNOTS, sknots, T_NUMKNOTS, tknots,
  284.             4*T_NUMPOINTS, 4, &ctlpoints[0][0][0], S_ORDER,
  285.             T_ORDER, GL_MAP2_VERTEX_4);
  286.     gluEndSurface(theNurbs);
  287.  
  288.     glPopMatrix();
  289.  
  290.     glFlush();
  291.  
  292.     if (doubleBuffer) {
  293.     tkSwapBuffers();
  294.     }
  295. }
  296.  
  297. static GLenum Args(int argc, char **argv)
  298. {
  299.     GLint i;
  300.  
  301.     doubleBuffer = GL_FALSE;
  302.     directRender = GL_TRUE;
  303.  
  304.     for (i = 1; i < argc; i++) {
  305.     if (strcmp(argv[i], "-sb") == 0) {
  306.         doubleBuffer = GL_FALSE;
  307.     } else if (strcmp(argv[i], "-db") == 0) {
  308.         doubleBuffer = GL_TRUE;
  309.     } else if (strcmp(argv[i], "-dr") == 0) {
  310.         directRender = GL_TRUE;
  311.     } else if (strcmp(argv[i], "-ir") == 0) {
  312.         directRender = GL_FALSE;
  313.     } else {
  314.         printf("%s (Bad option).\n", argv[i]);
  315.         return GL_FALSE;
  316.     }
  317.     }
  318.     return GL_TRUE;
  319. }
  320.  
  321. void main(int argc, char **argv)
  322. {
  323.     GLenum type;
  324.  
  325.     if (Args(argc, argv) == GL_FALSE) {
  326.     tkQuit();
  327.     }
  328.  
  329.     tkInitPosition(0, 0, 300, 300);
  330.  
  331.     type = TK_RGB;
  332.     type |= (doubleBuffer) ? TK_DOUBLE : TK_SINGLE;
  333.     type |= (directRender) ? TK_DIRECT : TK_INDIRECT;
  334.     tkInitDisplayMode(type);
  335.  
  336.     if (tkInitWindow("NURBS Test") == GL_FALSE) {
  337.     tkQuit();
  338.     }
  339.  
  340.     Init();
  341.  
  342.     tkExposeFunc(Reshape);
  343.     tkReshapeFunc(Reshape);
  344.     tkKeyDownFunc(Key);
  345.     tkDisplayFunc(Draw);
  346.     tkExec();
  347. }
  348.