当我在OpenGL中启用照明时,为什么我的颜色会消失?

时间:2011-12-13 19:24:04

标签: c++ opengl glut

我正在使用OpenGL API和GLUT在C ++中开发图形应用程序。

为了添加光照,我在模型视图矩阵中进行了以下更改:

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

// Create light components.
GLfloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8, 1.0f };
GLfloat specularLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat position[] = { 0.0f, 0.0f, 0.0f, 1.0f };

// Assign created components to GL_LIGHT0.
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
glLightfv(GL_LIGHT0, GL_POSITION, position);

我认为照明很有用,但我的物体的颜色都消失了。我所看到的只是我整体身材的黑/白轮廓。

我想知道为什么会这样?

2 个答案:

答案 0 :(得分:30)

启用光照时,不会根据glColorglColorPointer设置的颜色确定顶点颜色,而是使用照明计算将当前设置的材质颜色与灯光颜色组合。

因此,为了更改对象的颜色,您需要在渲染之前使用glMaterial函数更改材质设置(默认情况下为漫反射灰色材质)。每种不同的浅色(GL_DIFFUSE,...)基本上都有相应的材料颜色,还有一些附加的属性来近似发光材料(GL_EMISSION)和控制材料的粗糙度({{ 1}})。阅读一些关于OpenGL照明功能的介绍性材料,以了解它们的工作原理。

如何快速调整代码,从简单着色到照明(或启用每个顶点材质),可以使用颜色材料。通过调用GL_SHININESS并使用glColorMaterial设置适当的映射,您可以配置OpenGL以更改特定材质颜色,每当您更改当前顶点颜色时(使用glEnable(GL_COLOR_MATERIAL)glColor )。

答案 1 :(得分:20)

尝试glEnable(GL_COLOR_MATERIAL)

请参阅Common OpenGL Pitfall #14

  
      
  1. 小心启用色彩材料
  2.         

    OpenGL的色彩材质功能提供了一种更便宜的方式   改变材料参数。启用色料,材质   颜色跟踪当前颜色。这意味着不要使用   相对昂贵的glMaterialfv例程,你可以使用   glColor3f例程。

         

    以下是使用颜色材质功能更改的示例   三角形每个顶点的漫反射颜色:

    glColorMaterial(GL_FRONT, GL_DIFFUSE);
    glEnable(GL_COLOR_MATERIAL);
    glBegin(GL_TRIANGLES);
        glColor3f(0.2, 0.5, 0.8);
        glVertex3f(1.0, 0.0, 0.0);
        glColor3f(0.3, 0.5, 0.6);
        glVertex3f(0.0, 0.0, 0.0);
        glColor3f(0.4, 0.2, 0.2);
        glVertex3f(1.0, 1.0, 0.0);
    glEnd();
    
         

    考虑glMaterialfv所需的更昂贵的代码序列   明确使用:

    GLfloat d1[] = { 0.2, 0.5, 0.8, 1.0 };
    GLfloat d2[] = { 0.3, 0.5, 0.6, 1.0 };
    GLfloat d3[] = { 0.4, 0.2, 0.2, 1.0 };
    
    glBegin(GL_TRIANGLES);
        glMaterialfv(GL_FRONT,GL_DIFFUSE,d1);
        glVertex3f(1.0, 0.0, 0.0);
        glMaterialfv(GL_FRONT,GL_DIFFUSE,d2);
        glVertex3f(0.0, 0.0, 0.0);
        glMaterialfv(GL_FRONT,GL_DIFFUSE,d3);
        glVertex3f(1.0, 1.0, 0.0);
    glEnd();
    
         

    如果要渲染需要频繁简单材质的对象   更改,尝试使用颜色材质模式。但是,有一个   启用颜色材料模式时遇到的常见陷阱。什么时候   启用了颜色材质,OpenGL立即更改材质   由颜色材料状态控制的颜色。考虑以下   用于初始化新创建的OpenGL渲染上下文的代码片段:

    GLfloat a[] = { 0.1, 0.1, 0.1, 1.0 };
    glColor4f(1.0, 1.0, 1.0, 1.0);
    
    glMaterialfv(GL_FRONT, GL_AMBIENT, a);
    glEnable(GL_COLOR_MATERIAL); /* WARNING: Ambient and diffuse material latch immediately to the current color. */
    glColorMaterial(GL_FRONT, GL_DIFFUSE);
    glColor3f(0.3, 0.5, 0.6);
    
         

    前面的环境和漫反射材料的颜色是什么状态   执行上面的代码片段?虽然程序员可能有   将环境材料状态设为(0.1, 0.1, 0.1, 1.0)和   漫反射材料状态为(0.3, 0.5, 0.6, 1.0),而不是   发生了什么。

         

    产生的漫反射材料状态是程序员想要的,   但是由此产生的环境材料状态出乎意料(1.0, 1.0, 1.0, 1.0)。那是怎么发生的?好吧,请记住颜色材料模式立即开始跟踪当前颜色   启用。颜色材质设置的初始值为   GL_FRONT_AND_BACKGL_AMBIENT_AND_DIFFUSE(可能不是什么   你期待的!)。

         

    由于启用色料模式立即开始跟踪   当前颜色,环境和漫射材料状态都是   已更新为(1.0, 1.0, 1.0, 1.0)。注意效果了   初始glMaterialfv丢失了。接下来,颜色材料状态是   更新为仅更改前漫反射材质。最后,   glColor3f调用会将漫反射材质更改为(0.3, 0.5, 0.6, 1.0)。环境材料状态最终为(1.0, 1.0, 1.0, 1.0)

         

    上面代码片段中的问题是色料模式   在调用glColorMaterial之前启用。色料模式   对于有效的简单材料更改非常有效,但要避免   上述陷阱,请务必先设置glColorMaterial   启用GL_COLOR_MATERIAL