title: OpenGL NURBS surface
body: <p>I'm learning OpenGL and I want to get a surface with a slight hump in the middle. I'm currently using this code and im not sure how to adjust the ctrl points to make it the way i want. Its currently like </p>
  
  <p><img src="https://i.stack.imgur.com/MNg0o.png" alt="enter image description here"></p>
  
  <p>and i would like to have it like this: </p>
  
  <p><img src="https://i.stack.imgur.com/ABgar.png" alt="enter image description here"></p>
  
  <p>im not entirely sure what control points i should use and i'm confused on how it works. </p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;GLUT/glut.h&gt;
  
  GLfloat ctrlpoints[4][4][3] = {
     {{-1.5, -1.5, 4.0}, {-0.5, -1.5, 2.0}, 
      {0.5, -1.5, -1.0}, {1.5, -1.5, 2.0}}, 
     {{-1.5, -0.5, 1.0}, {-0.5, -0.5, 3.0}, 
      {0.5, -0.5, 0.0}, {1.5, -0.5, -1.0}}, 
     {{-1.5, 0.5, 4.0}, {-0.5, 0.5, 0.0}, 
      {0.5, 0.5, 3.0}, {1.5, 0.5, 4.0}}, 
     {{-1.5, 1.5, -2.0}, {-0.5, 1.5, -2.0}, 
      {0.5, 1.5, 0.0}, {1.5, 1.5, -1.0}}
  };
  
  void display(void)
  {
     int i, j;
  
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glColor3f(1.0, 1.0, 1.0);
     glPushMatrix ();
     glRotatef(85.0, 1.0, 1.0, 1.0);
     for (j = 0; j &lt;= 8; j++) {
        glBegin(GL_LINE_STRIP);
        for (i = 0; i &lt;= 30; i++)
           glEvalCoord2f((GLfloat)i/30.0, (GLfloat)j/8.0);
        glEnd();
        glBegin(GL_LINE_STRIP);
        for (i = 0; i &lt;= 30; i++)
           glEvalCoord2f((GLfloat)j/8.0, (GLfloat)i/30.0);
        glEnd();
     }
     glPopMatrix ();
     glFlush();
  }
  
  void init(void)
  {
     glClearColor (0.0, 0.0, 0.0, 0.0);
     glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4,
             0, 1, 12, 4, &amp;ctrlpoints[0][0][0]);
     glEnable(GL_MAP2_VERTEX_3);
     glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0);
     glEnable(GL_DEPTH_TEST);
     glShadeModel(GL_FLAT);
  }
  void reshape(int w, int h)
  {
     glViewport(0, 0, (GLsizei) w, (GLsizei) h);
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
     if (w &lt;= h)
        glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w, 
                 5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);
     else
        glOrtho(-5.0*(GLfloat)w/(GLfloat)h, 
                 5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0);
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
  }
  
  int main(int argc, char** argv)
  {
     glutInit(&amp;argc, argv);
     glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
     glutInitWindowSize (500, 500);
     glutInitWindowPosition (100, 100);
     glutCreateWindow (argv[0]);
     init ();
     glutDisplayFunc(display);
     glutReshapeFunc(reshape);
     glutMainLoop();
     return 0;
  }
  </code></pre>