OpenGL照明和闪亮

时间:2011-11-03 13:54:32

标签: c++ opengl

我必须将照明放在OpenGL图片中,但我不知道如何放置正确的点光照明,如下图所示:

Right

现在我尝试了不同的照明模式,结果如下:(

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);

编辑04/11/2011 0.39 CET

我还附上了由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();

  }

在显示的实践中,我写了构成我所代表的2°图形的小区域(我省略了计算每个区域的点的算法,因为它有效)。

我的目标是获得类似于图1的闪电和渲染图的结果,但我只获得了图2中的结果。

我不知道如何正确放置光线以及如何设置我的图形以进行渲染(如镜像)。

2 个答案:

答案 0 :(得分:1)

你缺少法线。您需要为每个顶点提供一个法线(glNormal),或者如果您使用glMap2(您不是),则可以启用GL_AUTO_NORMALS。有一篇关于如何在opengl.org上发表compute normals for a triangle or polygons的文章,你可能会发现它很有用。

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

从您发布的结果图像中,您似乎正在计算并绘制法线(红色箭头),而不是应用它们。

答案 1 :(得分:0)

无法确定您的代码发生了什么。我希望你的坐标介于-1到+1之间。我建议你使用简单的原语来处理照明。你的表面生成的工作。光源的位置和计算法线是最重要的一点。

http://www.falloutsoftware.com/tutorials/gl/gl8.htm

http://glprogramming.com/red/chapter05.html