Search code examples
c++openglmodelshadercube

No color interpolation using glShadeModel(GL_SMOOTH)


Current and wanted output
Current and wanted output

I'm trying to get Color Interpolation/ Color gradient in a 3D Cube using glShadeModel(GL_SMOOTH) which I heard is default, but it doesn't work for some reason. It looks like it's using glShadeModel(GL_FLAT), without me declaring it. What am I doing wrong?

Source Code:

  void drawObj (CGFobject *obj)
{ int jF, jP, dummyi=0;
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix (); 
  move();
  if (!strncmp (obj->Name, "Triangle", strlen("Triangle"))) {;
  }
  glShadeModel(GL_SMOOTH);
  for (jF=0; jF < obj->nFace; jF++)
  {
    if (!jF) { 
        glLineStipple(2, 0xAAAA); }
    else{ 
        glLineStipple(2, 0xAAAA); }
        if (wire == GL_FILL && shade == GL_FLAT) glColor4fv(colors[jF]);
        glBegin(GL_POLYGON);
    for (jP=0; jP < obj->Face[jF].nPnt; jP++)
    {
      glVertex3fv(*obj->Face[jF].Pnt[jP]);
    } 
    glEnd();
  }
  glPopMatrix ();
}
  void display (void)
{ glClear(GL_COLOR_BUFFER_BIT);
  nah=eyez; fern=nah+2*diag;
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  if (persp) /*Perspective:*/
  {
    glViewport(winWidth*(1-viewScale)/2, winHeight*(1-viewScale)/2, 
               winWidth*viewScale,       winHeight*viewScale); 
    glFrustum (-diag, diag, -diag, diag, nah, fern);
  } else /*Parallel-Projection:*/
  { glViewport(0, 0, winWidth, winHeight); 
    glOrtho (-diag, diag, -diag, diag, nah, fern);
  }
  if (backF) glEnable  (GL_CULL_FACE);
  else       glDisable (GL_CULL_FACE);
  if (aa && wire == GL_LINE) 
  { glEnable (GL_POINT_SMOOTH); glEnable (GL_LINE_SMOOTH);
    glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  } else    { glDisable (GL_POINT_SMOOTH); glDisable (GL_LINE_SMOOTH);
              glDisable (GL_BLEND); }
  glPolygonMode(GL_FRONT_AND_BACK, wire);
  glLineWidth((GLfloat)1.5f);
  if (stipple)
      glEnable(GL_LINE_STIPPLE);
  else
      glDisable(GL_LINE_STIPPLE);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity(); 
  drawObj(&obj); 
}

Solution

  • but it doesn't work for some reason. It looks like it's using glShadeModel(GL_FLAT), without me declaring it. What am I doing wrong?

    When you use glShadeModel(GL_SMOOTH), then the color of the fragments is calculated by interpolating the color attributes of the vertices according to the Barycentric coordinate within a triangular primitive.

    But in your case the colors are specified per face and not per vertex. This means the colors attributes of the vertices, which define a face are identically. So identical colors are interpolated, and you gain a "flat" look.

    You have to set different colors attributes per vertex coordinate and not only per faces, to solve the issue:

    glShadeModel(GL_SMOOTH);
    for (jF=0; jF < obj->nFace; jF++)
    {
        .....
    
        // if you would set the color here,
        // then every vertex of a face would have the same color attribute
    
        glBegin(GL_POLYGON);
        for (jP=0; jP < obj->Face[jF].nPnt; jP++)
        {
            glColor4fv( .... ); // <------------- set different color attributes per vertex
            glVertex3fv(*obj->Face[jF].Pnt[jP]);
        } 
        glEnd();
    }