Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL illumination and shining

Tags:

c++

opengl

I have to put illumination in a OpenGL picture but i don't know how to put a correct point light illumination like in the following picture:

Right

For now i had tried different mode of illumination, but the result is the following :(

Wrong

I attach you the code that I used for my result. What is wrong?

    float specref[] = { 1.0f, 1.0f, 1.0f, 1.0f };
    // Light values and coordinates
    float ambientLight[] = { 0.3f, 0.3f, 0.3f, 1.0f };
    float diffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f };
    float specular[] = { 1.0f, 1.0f, 1.0f, 1.0f};
    float lightPos[] = { 0.0f, -150.0f, -150.0f, 1.0f };

    glEnable ( GL_LIGHTING ) ;

    glLightfv(GL_LIGHT0,GL_AMBIENT, ambientLight);
    glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
    glLightfv(GL_LIGHT0,GL_SPECULAR,specular);
    glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
    glEnable(GL_LIGHT0);
    glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,specref);
    glMateriali(GL_FRONT_AND_BACK,GL_SHININESS,128);
    glEnable ( GL_COLOR_MATERIAL ) ;

    glClearColor (1.0, 1.0, 1.0, 1.0);
    glColor3f(0.0,0.0,0.0);

Edit 04/11/2011 0.39 CET

I attach also my display() function called by glutDisplayFunc(display);

  void display(void)

  {

  [...]

  //Draw polygons in 3d

  glColor3f(0.0,1.0,1.0);

  glBegin(GL_QUADS);

  for(i=0;i<NVERT-1;i++) {

        for (j=0;j<NVERT-1;j++) {

              glVertex3f( (GLfloat)((sb[i*NVERT+j]).x()),

                                      (GLfloat)((sb[i*NVERT+j]).y()),

                                      (GLfloat)((sb[i*NVERT+j]).z()));


              glVertex3f( (GLfloat)((sb[i*NVERT+j+1]).x()),

                                      (GLfloat)((sb[i*NVERT+j+1]).y()),

                                      (GLfloat)((sb[i*NVERT+j+1]).z()));


              glVertex3f( (GLfloat)((sb[(i+1)*NVERT+j+1]).x()),

                                      (GLfloat)((sb[(i+1)*NVERT+j+1]).y()),

                                      (GLfloat)((sb[(i+1)*NVERT+j+1]).z()));


              glVertex3f( (GLfloat)((sb[(i+1)*NVERT+j]).x()),

                                      (GLfloat)((sb[(i+1)*NVERT+j]).y()),

                                      (GLfloat)((sb[(i+1)*NVERT+j]).z()));


        }



  }

  glEnd();
  glFlush();

  }

In practice with display I write the small areas that compose the 2° figure that i represented (I omitted the algorithm for the calculation of the points of each area because is it working).

My goal is to have a result similar to figure 1 for the lightning and rendering of the figure but I only obtained the result in figure 2.

I don't know how to put correctly the light and how to setup my figure in order to have this render (like mirror).

like image 378
flatlopa Avatar asked Nov 14 '22 15:11

flatlopa


1 Answers

You're missing normals. You either need to provide one normal per vertex (glNormal) or you could enable GL_AUTO_NORMALS if you use glMap2 (which you are not). There's an article on how to compute normals for a triangle or polygons on opengl.org that you probably will find useful.

Begin Function CalculateSurfaceNormal (Input Polygon) Returns Vector

   Set Vertex Normal to (0, 0, 0)

   Begin Cycle for Index in [0, Polygon.vertexNumber)

      Set Vertex Current to Polygon.verts[Index]
      Set Vertex Next    to Polygon.verts[(Index plus 1) mod Polygon.vertexNumber]

      Set Normal.x to Sum of Normal.x and (multiply (Current.y minus Next.y) by (Current.z plus Next.z))
      Set Normal.y to Sum of Normal.y and (multiply (Current.z minus Next.z) by (Current.x plus Next.x))
      Set Normal.z to Sum of Normal.z and (multiply (Current.x minus Next.x) by (Current.y plus Next.y))

   End Cycle

   Returning Normalize(Normal)

End Function

From the image you posted of the results it seems you are calculating and drawing the normals (red arrows), just not applying them.

like image 185
larsmoa Avatar answered Dec 27 '22 22:12

larsmoa