title: Transition of opening the box is not seamless
body: <p>I wanted to simulate a box opening such that first each triangle on top of the box opens one by one and then each side of box completely opens one by one.</p>
  
  <p>My approach to solve the problem was having 4 triangles on top of the box and 4 rectangles on the side that do not move at all. When triangles on top of the box start rotating and they reach 90 degrees then triangles and rectangles will be replaced by 4 Pentagons exactly the same size.</p>
  
  <p><strong>Problem:</strong></p>
  
  <p><strong>The problem I encountered was the transition from having 4 triangles and 4 rectangles to having 4 pentagons is not seamless and it is easily noticeable due to the lighting.</strong></p>
  
  <p>As you can see when triangles pass 90 degree then color of each pentagon changes and becomes darker</p>
  
  <p><img src="https://i.stack.imgur.com/1RrmZ.jpg" alt="enter image description here"></p>
  
  <p><img src="https://i.stack.imgur.com/DEOOq.jpg" alt="enter image description here"></p>
  
  <p><img src="https://i.stack.imgur.com/fnTpc.jpg" alt="enter image description here"></p>
  
  <pre><code>#include &lt;GL/glut.h&gt;
  #include &lt;math.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  
  #define PI 3.14159265
  static int step = 0, step1, step2, step3, step4, step5, step6, step7, step8;
  
  /* camera location in longitude and latitude */
  static float alpha = 0.0;
  static float beta = PI / 6.0;
  
  /* position of camera */
  static GLdouble cpos[3];
  
  /* position of light source */
  static GLfloat lpos[] = { -2.5, 2.5, 3.0, 1.0 };
  
  /* vectors to specify material properties */
  static GLfloat black[] = { 0.0, 0.0, 0.0, 1.0 };
  static GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 };
  static GLfloat gray[] = { 0.5, 0.5, 0.5, 1.0 };
  static GLfloat red[] = { 1.0, 0.0, 0.0, 1.0 };
  static GLfloat green[] = { 0.0, 1.0, 0.0, 1.0 };
  static GLfloat blue[] = { 0.0, 0.0, 1.0, 1.0 };
  static GLfloat yellow[] = { 1.0, 1.0, 0.0, 1.0 };
  static GLfloat magenta[] = { 1.0, 0.0, 1.0, 1.0 };
  static GLfloat cyan[] = { 0.0, 1.0, 1.0, 1.0 };
  static GLfloat darkcyan[] = { 0.0, 0.4, 0.4, 1.0 };
  static GLfloat gold[] = { 255.0 / 255.0, 215.0 / 255.0, 0 / 255.0 };
  static GLfloat silver[] = { 204.0 / 255.0, 204.0 / 255.0, 204.0 / 255.0 };
  
  static bool trianglesExist = false;
  static float stepBefore = step;
  
  static float zoom = 10.0;
  
  void writemessage()
  {
      printf("HW-1");
  }
  
  void init(void)
  {
      writemessage();
  
      glClearColor(0.0, 0.0, 0.0, 0.0);
      glEnable(GL_DEPTH_TEST);
      glShadeModel(GL_SMOOTH);
  
      /* initially GL_FILL mode (default), later GL_LINE to show wireframe */
      glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  
      glEnable(GL_LIGHTING);
      glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
      glEnable(GL_LIGHT0);
  }
  
  
  
  void reshape(int w, int h)
  {
      glViewport(0, 0, (GLsizei)w, (GLsizei)h);
  
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      gluPerspective(75.0, (GLfloat)w / (GLfloat)h, 1.0, 20.0);
  
      glMatrixMode(GL_MODELVIEW);
  }
  
  void display(void)
  {
      static int i;
      static double angle1, angle2, angle3, angle4, Y1, Z1, Y2, Z2, X3, Y3, X4, Y4;
      static double angle5, angle6, angle7, angle8, X5, Y5, X6, Y6, X7, Y7, X8, Y8;
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  
      /* initialize (modelview) matrix */
      glLoadIdentity();
  
      /* update camera position */
      cpos[0] = zoom * cos(beta) * sin(alpha);
      cpos[1] = zoom * sin(beta);
      cpos[2] = zoom * cos(beta) * cos(alpha);
      gluLookAt(cpos[0], cpos[1], cpos[2], 0.0, 1.0, 0.0, 0.0, 1.0, 0.0);
  
      /* set current light source position */
      glLightfv(GL_LIGHT0, GL_POSITION, lpos);
  
      /* draw sphere to show light source */
      glMaterialfv(GL_FRONT, GL_EMISSION, white);
      glPushMatrix();
      glTranslatef(lpos[0], lpos[1], lpos[2]);
      glutSolidSphere(0.1, 10, 8);
      glPopMatrix();
  
      /* remaining objects do not look as if they emit light */
      glMaterialfv(GL_FRONT, GL_EMISSION, black);
  
      /* draw a tabletop */
      glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue);
      glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, white);
      glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 64);
      glNormal3f(0.0, 1.0, 0.0);
      glBegin(GL_POLYGON);
      glVertex3f(-5.0, -0.001, -3.0);
      glVertex3f(-5.0, -0.001, 5.0);
      glVertex3f(5.0, -0.001, 5.0);
      glVertex3f(5.0, -0.001, -3.0);
      glEnd();
  
      printf("%d", step);
      printf("\n");
  
      if (step &lt;= 360)
          trianglesExist = true;
      else
          trianglesExist = false;
  
      if (step &gt; 630 &amp;&amp; step &lt; 720){
          step1 = 90;
          step2 = 90;
          step3 = 90;
          step4 = 90;
          step5 = 90;
          step6 = 90;
          step7 = 90;
          step8 = step - 630;
      }
  
      else if (step &gt; 540 &amp;&amp; step &lt; 720){
          step1 = 90;
          step2 = 90;
          step3 = 90;
          step4 = 90;
          step5 = 90;
          step6 = 90;
          step7 = step - 540;
          step8 = 0;
      }
      else if (step &gt; 450 &amp;&amp; step &lt; 720){
          step1 = 90;
          step2 = 90;
          step3 = 90;
          step4 = 90;
          step5 = 90;
          step6 = step - 450;
          step7 = 0;
          step8 = 0;
      }
      else if (step &gt; 360 &amp;&amp; step &lt; 720){
          step1 = 90;
          step2 = 90;
          step3 = 90;
          step4 = 90;
          step5 = step - 360;
          step6 = 0;
          step7 = 0;
          step8 = 0;
      }
      else if (step &gt; 270 &amp;&amp; step &lt;= 360)
      {
          step1 = 90;
          step2 = 90;
          step3 = 90;
          step4 = step - 270;
          step5 = 0;
          step6 = 0;
          step7 = 0;
          step8 = 0;
  
      }
      else if (step &gt; 180 &amp;&amp; step &lt;= 360)
      {
          step1 = 90;
          step2 = 90;
          step3 = step - 180;
          step4 = 0;
          step5 = 0;
          step6 = 0;
          step7 = 0;
          step8 = 0;
  
      }
      else if (step &gt; 90 &amp;&amp; step &lt;= 360)
      {
          step1 = 90;
          step2 = step - 90;
          step3 = 0;
          step4 = 0;
          step5 = 0;
          step6 = 0;
          step7 = 0;
          step8 = 0;
      }
      else if (step &gt;= 0 &amp;&amp; step &lt;= 360)
      {
          step1 = step;
          step2 = 0;
          step3 = 0;
          step4 = 0;
          step5 = 0;
          step6 = 0;
          step7 = 0;
          step8 = 0;
      }
      else;
      if (trianglesExist)
      {
          // first
          glMaterialfv(GL_FRONT, GL_EMISSION, black);
          glMaterialfv(GL_BACK, GL_EMISSION, black);
          glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, gold);
          glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, silver);
          glMaterialf(GL_BACK, GL_SHININESS, 128);
          glMaterialf(GL_FRONT, GL_SHININESS, 128);
          angle1 = ((float)step1 / 180) * PI;
          Y1 = 2.0 + 2.0 * sin(angle1);
          Z1 = -1.0 + 2.0 * cos(angle1);
          glNormal3f(0, sin(angle1), cos(angle1));
          glBegin(GL_POLYGON);
          glVertex3f(-3.0, 2.0, -1.0);
          glVertex3f(3.0, 2.0, -1.0);
          glVertex3f(0, Y1, Z1);
          glEnd();
  
          // second
          glMaterialfv(GL_FRONT, GL_EMISSION, black);
          glMaterialfv(GL_BACK, GL_EMISSION, black);
          glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, gold);
          glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, silver);
          glMaterialf(GL_BACK, GL_SHININESS, 128);
          glMaterialf(GL_FRONT, GL_SHININESS, 128);
          angle2 = ((float)step2 / 180) * PI;
          Y2 = 2.0 + 2.0 * sin(angle2);
          Z2 = 3.0 + -2.0 * cos(angle2);
          glNormal3f(0, sin(angle2), cos(angle2));
          glBegin(GL_POLYGON);
          glVertex3f(-3.0, 2.0, 3.0);
          glVertex3f(3.0, 2.0, 3.0);
          glVertex3f(0, Y2, Z2);
          glEnd();
  
          // third
          glMaterialfv(GL_FRONT, GL_EMISSION, black);
          glMaterialfv(GL_BACK, GL_EMISSION, black);
          glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, gold);
          glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, silver);
          glMaterialf(GL_BACK, GL_SHININESS, 128);
          glMaterialf(GL_FRONT, GL_SHININESS, 128);
          angle3 = ((float)step3 / 180) * PI;
          X3 = 3.0 - 3.0 * cos(angle3);
          Y3 = 2.0 + 2.0 * sin(angle3);
          glNormal3f(sin(angle3), cos(angle3), 0);
          glBegin(GL_POLYGON);
          glVertex3f(3.0, 2.0, 3.0);
          glVertex3f(3.0, 2.0, -1.0);
          glVertex3f(X3, Y3, 1);
          glEnd();
  
          // fourth
          glMaterialfv(GL_FRONT, GL_EMISSION, black);
          glMaterialfv(GL_BACK, GL_EMISSION, black);
          glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, gold);
          glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, silver);
          glMaterialf(GL_BACK, GL_SHININESS, 128);
          glMaterialf(GL_FRONT, GL_SHININESS, 128);
          angle4 = ((float)step4 / 180) * PI;
          X4 = -3.0 + 3.0 * cos(angle4);
          Y4 = 2.0 + 2.0 * sin(angle4);
          glNormal3f(sin(angle4), cos(angle4), 0);
          glBegin(GL_POLYGON);
          glVertex3f(-3.0, 2.0, 3.0);
          glVertex3f(-3.0, 2.0, -1.0);
          glVertex3f(X4, Y4, 1);
          glEnd();
  
  
          // back
          glMaterialfv(GL_FRONT, GL_EMISSION, black);
          glMaterialfv(GL_BACK, GL_EMISSION, black);
          glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, gold);
          glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, silver);
          glMaterialf(GL_BACK, GL_SHININESS, 128);
          glMaterialf(GL_FRONT, GL_SHININESS, 128);
          glBegin(GL_POLYGON);
          glNormal3f(0, 0, -1);
          glVertex3f(3.0, 0.0, -1.0);
          glVertex3f(3.0, 2.0, -1.0);
          glVertex3f(-3.0, 2.0, -1.0);
          glVertex3f(-3.0, 0.0, -1.0);
          glEnd();
  
          // front
          glMaterialfv(GL_FRONT, GL_EMISSION, black);
          glMaterialfv(GL_BACK, GL_EMISSION, black);
          glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, gold);
          glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, silver);
          glMaterialf(GL_BACK, GL_SHININESS, 128);
          glMaterialf(GL_FRONT, GL_SHININESS, 128);
          glBegin(GL_POLYGON);
          glNormal3f(0, 0, 1);
          glVertex3f(3.0, 0.0, 3.0);
          glVertex3f(3.0, 2.0, 3.0);
          glVertex3f(-3.0, 2.0, 3.0);
          glVertex3f(-3.0, 0.0, 3.0);
          glEnd();
  
          // right
          glMaterialfv(GL_FRONT, GL_EMISSION, black);
          glMaterialfv(GL_BACK, GL_EMISSION, black);
          glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, gold);
          glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, silver);
          glMaterialf(GL_BACK, GL_SHININESS, 128);
          glMaterialf(GL_FRONT, GL_SHININESS, 128);
          glBegin(GL_POLYGON);
          glNormal3f(1, 0, 0);
          glVertex3f(3.0, 2.0, -1.0);
          glVertex3f(3.0, 2.0, 3.0);
          glVertex3f(3.0, 0.0, 3.0);
          glVertex3f(3.0, 0.0, -1.0);
          glEnd();
  
          // left
          glMaterialfv(GL_FRONT, GL_EMISSION, black);
          glMaterialfv(GL_BACK, GL_EMISSION, black);
          glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, gold);
          glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, silver);
          glMaterialf(GL_BACK, GL_SHININESS, 128);
          glMaterialf(GL_FRONT, GL_SHININESS, 128);
          glBegin(GL_POLYGON);
          glNormal3f(-1, 0, 0);
          glVertex3f(-3.0, 2.0, -1.0);
          glVertex3f(-3.0, 2.0, 3.0);
          glVertex3f(-3.0, 0.0, 3.0);
          glVertex3f(-3.0, 0.0, -1.0);
          glEnd();
  
      }
      else{
          // right-full
          glMaterialfv(GL_FRONT, GL_EMISSION, black);
          glMaterialfv(GL_BACK, GL_EMISSION, black);
          glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, gold);
          glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, silver);
          glMaterialf(GL_BACK, GL_SHININESS, 128);
          glMaterialf(GL_FRONT, GL_SHININESS, 128);
          glBegin(GL_POLYGON);
          angle5 = ((float)step5 / 180) * PI;
          angle5 = angle5 + PI / 2;
          glNormal3f(sin(angle5), cos(angle5), 0);
          glVertex3f(3.0 - 2 * cos(angle5), 2 * sin(angle5), -1.0);
          glVertex3f(3.0 - 4 * cos(angle5), 4.0* sin(angle5), 1.0);
          glVertex3f(3.0 - 2 * cos(angle5), 2 * sin(angle5), 3.0);
          glVertex3f(3.0, 0.0, 3.0);
          glVertex3f(3.0, 0.0, -1.0);
          glEnd();
  
          // left-full
          glMaterialfv(GL_FRONT, GL_EMISSION, black);
          glMaterialfv(GL_BACK, GL_EMISSION, black);
          glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, gold);
          glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, silver);
          glMaterialf(GL_BACK, GL_SHININESS, 128);
          glMaterialf(GL_FRONT, GL_SHININESS, 128);
          glBegin(GL_POLYGON);
          angle6 = ((float)step6 / 180) * PI;
          angle6 = angle6 + PI / 2;
          glNormal3f(sin(angle6), cos(angle6), 0);
          glVertex3f(-3.0 + 2 * cos(angle6), 2 * sin(angle6), -1.0);
          glVertex3f(-3.0 + 4 * cos(angle6), 4.0* sin(angle6), 1.0);
          glVertex3f(-3.0 + 2 * cos(angle6), 2 * sin(angle6), 3.0);
          glVertex3f(-3.0, 0.0, 3.0);
          glVertex3f(-3.0, 0.0, -1.0);
          glEnd();
  
  
          // back-full
          glMaterialfv(GL_FRONT, GL_EMISSION, black);
          glMaterialfv(GL_BACK, GL_EMISSION, black);
          glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, gold);
          glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, silver);
          glMaterialf(GL_BACK, GL_SHININESS, 128);
          glMaterialf(GL_FRONT, GL_SHININESS, 128);
          glBegin(GL_POLYGON);
          angle7 = ((float)step7 / 180) * PI;
          angle7 = 2 * PI - angle7;
          glNormal3f(0, sin(angle7), cos(angle7));
          glVertex3f(3.0, 0, -1.0);
          glVertex3f(3.0, 2.0*cos(angle7), -1.0 + 2 * sin(angle7)); //
          glVertex3f(0, 4 * cos(angle7), -1.0 + 4 * sin(angle7)); //
          glVertex3f(-3.0, 2.0*cos(angle7), -1.0 + 2 * sin(angle7)); //
          glVertex3f(-3.0, 0.0, -1.0);
          glEnd();
  
  
          // front-full
          glMaterialfv(GL_FRONT, GL_EMISSION, black);
          glMaterialfv(GL_BACK, GL_EMISSION, black);
          glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, gold);
          glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, silver);
          glMaterialf(GL_BACK, GL_SHININESS, 128);
          glMaterialf(GL_FRONT, GL_SHININESS, 128);
          glBegin(GL_POLYGON);
          angle8 = ((float)step8 / 180) * PI;
          glNormal3f(0, sin(angle8), cos(angle8));
          glVertex3f(3.0, 0, 3.0);
          glVertex3f(3.0, 2.0*cos(angle8), 3.0 + 2 * sin(angle8)); //
          glVertex3f(0, 4 * cos(angle8), 3.0 + 4 * sin(angle8)); //
          glVertex3f(-3.0, 2.0*cos(angle8), 3.0 + 2 * sin(angle8)); //
          glVertex3f(-3.0, 0.0, 3.0);
          glEnd();
      }
  
      // buttom
      glMaterialfv(GL_FRONT, GL_EMISSION, black);
      glMaterialfv(GL_BACK, GL_EMISSION, black);
      glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, gold);
      glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, silver);
      glMaterialf(GL_BACK, GL_SHININESS, 128);
      glMaterialf(GL_FRONT, GL_SHININESS, 128);
      glBegin(GL_POLYGON);
      glNormal3f(0, -1, 0);
      glVertex3f(-3.0, 0.0, -1.0);
      glVertex3f(-3.0, 0.0, 3.0);
      glVertex3f(3.0, 0.0, 3.0);
      glVertex3f(3.0, 0.0, -1.0);
      glEnd();
  
      glFlush();
      glutSwapBuffers();
  }
  
  
  void keyboard(unsigned char key, int x, int y)
  {
      static int polygonmode[2];
  
      switch (key) {
      case 27:
          exit(0);
          break;
  
          /* open and close the top */
      case 'o':
          if (step &lt; 720) { stepBefore = step*1.0; step = step + 2; }
          glutPostRedisplay();
          break;
      case 'c':
          if (step &gt; 0) {
              stepBefore = step*1.0; step = step - 2;
          }
          glutPostRedisplay();
          break;
          /* w for switching between GL_FILL and GL_LINE
          * Using a query command glGetIntegerv() we obtain two integers
          * indicating the current GL_POLYGON_MODE for FRONT and BACK faces.
          * Look up glIsEnabled() that may be found useful. */
      case 'w':
          glGetIntegerv(GL_POLYGON_MODE, polygonmode);
          if (polygonmode[0] == GL_FILL)
              glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
          else glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
          glutPostRedisplay();
          break;
  
          /* control lpos */
      case 'x':
          lpos[0] = lpos[0] + 0.2;
          glutPostRedisplay();
          break;
      case 'X':
          lpos[0] = lpos[0] - 0.2;
          glutPostRedisplay();
          break;
      case 'y':
          lpos[1] = lpos[1] + 0.2;
          glutPostRedisplay();
          break;
      case 'Y':
          lpos[1] = lpos[1] - 0.2;
          glutPostRedisplay();
          break;
      case 'z':
          lpos[2] = lpos[2] + 0.2;
          glutPostRedisplay();
          break;
      case 'Z':
          lpos[2] = lpos[2] - 0.2;
          glutPostRedisplay();
          break;
      case '+':
          zoom++;
          glutPostRedisplay();
          break;
      case '-':
          zoom--;
          glutPostRedisplay();
          break;
  
      default:
          break;
      }
  }
  void specialkey(GLint key, int x, int y)
  {
      switch (key) {
      case GLUT_KEY_RIGHT:
          alpha = alpha + PI / 180;
          if (alpha &gt; 2 * PI) alpha = alpha - 2 * PI;
          glutPostRedisplay();
          break;
      case GLUT_KEY_LEFT:
          alpha = alpha - PI / 180;
          if (alpha &lt; 0) alpha = alpha + 2 * PI;
          glutPostRedisplay();
          break;
      case GLUT_KEY_UP:
          if (beta &lt; 0.45*PI) beta = beta + PI / 180;
          glutPostRedisplay();
          break;
      case GLUT_KEY_DOWN:
          if (beta &gt; 0.05*PI) beta = beta - PI / 180;
          glutPostRedisplay();
          break;
  
  
      default:
          break;
      }
  }
  
  int main(int argc, char** argv)
  {
      glutInit(&amp;argc, argv);
      glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
      glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
      glutInitWindowSize(800, 800);
      glutInitWindowPosition(100, 100);
      glutCreateWindow(argv[0]);
      init();
      glutDisplayFunc(display);
      glutReshapeFunc(reshape);
      glutKeyboardFunc(keyboard);
      glutSpecialFunc(specialkey);
      glutMainLoop();
      return 0;
  }
  </code></pre>