2011-12-13 141 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

    相關問題