OpenGL - 照明时多个对象上的GLmaterialfv问题

时间:2013-12-14 19:43:57

标签: visual-c++ opengl 3d lighting

情况:我正在使用OpenGL制作一个照明示例。我的目标是,如下图所示,将有20个随机彩色球体,一个立方体和三个光源。

http://i.stack.imgur.com/b4uwu.png

问题:上面看到的立方体只有在我移除了pushMatrix和Popmatrix时才受到光源的影响,但是当你看到这三个光源(红色,绿色和蓝色)平滑地影响了球体时。由于我无法实现的原因,立方体的颜色正在发生变化。我必须使这个立方体受到三个光源的影响,如球体,并且总是白色。

代码部分:

这是流星的绘制方法;

void meteor::draw(){

glPushMatrix();

   glTranslatef(posx,posy,posz);
   glutSolidSphere(radious,40,20);


   GLfloat MaterialColor[] = {red, green, blue, 1.0};
   GLfloat ambientColor[] = {red, green, blue, 1.0}; 

       glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambientColor);
   glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor);



glPopMatrix();

}

这是立方体的绘制方法;

void Ship::draw(){
 glPushMatrix();

   glTranslatef (posx, posy, 95.0);
   glutSolidCube(5.0);

       glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, MaterialColor1);
   glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor1);

 glPopMatrix();

}

这是绘制屏幕上所有对象的显示方法:

void display (void)
{
   GLfloat position0[] = { 8.0, -10.0, 100.0, 1.0}; //red
   GLfloat position1[] = { -8.0, -10.0, 100.0, 1.0};
   GLfloat position2[] = { 0.0, 10.0, 100.0, 1.0};

  GLfloat LightColor[]=  {1.0f,0.0f,0.0f};//red
    GLfloat LightColor1[]= {0.0f,1.0f,0.0f};//green
    GLfloat LightColor2[]= {0.0f,0.0f,1.0f};//blue

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glPushMatrix();

   gluLookAt (0.0, 0.0, 500.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);   


glPushMatrix();

            glLightfv (GL_LIGHT0, GL_POSITION, position0);
            glLightfv (GL_LIGHT0, GL_DIFFUSE, LightColor);



            glLightfv (GL_LIGHT1, GL_POSITION, position1);
            glLightfv (GL_LIGHT1, GL_DIFFUSE, LightColor1);


            glLightfv (GL_LIGHT2, GL_POSITION, position2);
            glLightfv (GL_LIGHT2, GL_DIFFUSE, LightColor2);


  //This is where the spheres are drawn
            for(iter1 = objects.begin(); iter1 != objects.end(); ++iter1)
                        {

                            (*iter1)->draw();


                        }
 //This is where the spheres are drawn

              shipCan->draw();



glPopMatrix ();

glPopMatrix();

glFlush();
}

如果你想看到剩下的代码,我可以提供它。

1 个答案:

答案 0 :(得分:0)

我找到了答案。每个人都应该首先了解OpenGL渲染管道。 OpenGL就像一台状态机。例如,如果您在绘制屏幕之前定义颜色,它会将其信息发送到图形卡。并且所有对象都采用这种颜色。如果在绘制另一个对象之前未更改此颜色,则颜色将保持不变。

我将所有glMaterialFv函数移到glPushMatrix()函数之外:

在:

void meteor::draw(){

glPushMatrix();

glTranslatef(posx,posy,posz);
glutSolidSphere(radious,40,20);


GLfloat MaterialColor[] = {red, green, blue, 1.0};
GLfloat ambientColor[] = {red, green, blue, 1.0}; 

   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambientColor);
   glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor);



glPopMatrix();

 }

现在:

void meteor::draw(){

 GLfloat MaterialColor[] = {red, green, blue, 1.0};
  GLfloat ambientColor[] = {red, green, blue, 1.0}; 

   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambientColor);
   glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialColor);

glPushMatrix();

glTranslatef(posx,posy,posz);
glutSolidSphere(radious,40,20);

glPopMatrix();

 }

通过此更改,我将材料信息发送到图形卡,然后绘制。所以屏幕上没有错误。