2011-12-13 73 views
24

我正在用OpenGL API和GLUT在C++中开发图形应用程序。当我在OpenGL中启用照明时,为什么我的颜色会消失?

要添加灯光,我改变了我的模型视图矩阵以下变化:

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

照明工程基本上我相信,但我的对象的颜色都赶不走。我看到的只是我整体身材的黑色/白色轮廓。

我在想这是为什么?

+1

良好的相关链接https://sjbaker.org/steve/omniv/opengl_lighting.html – 2016-03-18 11:11:50

回答

29

当启用照明,顶点”颜色不从颜色由glColorglColorPointer设置决定的,而是由当前设定的材料的颜色与灯结合使用照明计算颜色。

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

你能做些什么来快速调整你的代码从纯色到光照(或者为了实现每个顶点的材质属性)就是使用色彩材质。通过调用glEnable(GL_COLOR_MATERIAL)并使用glColorMaterial设置适当的映射,无论何时更改当前顶点颜色(使用glColor或),都可以配置OpenGL以更改特定的材质颜色。

+0

谢谢!那样做了。 – dangerChihuahua007 2011-12-13 20:21:43

19

尝试glEnable(GL_COLOR_MATERIAL)

参见Common OpenGL Pitfall #14

  • 仔细启用颜色材料
  • OpenGL的色材特性提供了一种较不昂贵的方式来 变材料参数。启用颜色材质后,材质 颜色会跟踪当前颜色。这意味着您可以使用例行程序代替使用 相对昂贵的例程glMaterialfv

    下面是使用的色彩材料特性来改变 漫反射颜色为一个三角形的每个顶点的例子:

    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

    相关问题