OpenGL照明的问题



当我在OpenGL中启用照明时,我很难看到我创建的对象。我有一个从3D Max导入的对象,该对象的照明工作正常,但场景的其余部分则不正常。我知道我需要指定法线,但这似乎没有帮助。虽然如果我在display((函数中创建一个简单的多边形,它可以正常工作,但在类的方法中创建并在display(

这是我的照明代码

glewInit();
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT) 
glShadeModel(GL_SMOOTH);
//light position and colour
GLfloat light_position[] = { 0.0, 0.0, 20.0,0.0 };
GLfloat white_light[] = {0.8,0.8,0.8,0.0};
GLfloat diff_light[] = {1.0,1.0,1.0,0.0};
GLfloat spec_light[] = {1.0,1.0,1.0,0.0};
glLightfv(GL_LIGHT0, GL_AMBIENT, white_light);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diff_light);
glLightfv(GL_LIGHT0, GL_SPECULAR, spec_light);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
//ambient light
GLfloat ambient[] = {0.3,0.3,0.3};
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
//diffuse material component
GLfloat diff[] = {0.6,0.6,0.6};
glMaterialfv(GL_FRONT, GL_DIFFUSE, diff);
//specular material component
GLfloat WhiteSpec[] = {1,1,1};
glMaterialfv(GL_FRONT, GL_SPECULAR, WhiteSpec);
GLfloat shininess = 50;
glMaterialf(GL_FRONT, GL_SHININESS, shininess);
//ENABLE LIGHTING AND DEPTH TEST
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);

这是我的类方法,它正在创建我的海洋

glColor3f(0,0,1);
glPushMatrix();
//enable texturing
glEnable(GL_TEXTURE_2D);    
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, seaTex);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
for(int i = 0, k = 0; i < (getWidth()/10); i++){
    for(int j = 0; j < (getLength()/10); j++){
        if(i >= Sea::waveLoc1 && i <= Sea::waveLoc1+Sea::sinArrayLength){
            int nextK = k+1;
            if(nextK == Sea::sinArrayLength){
                nextK = 0;
            }
            if(i == Sea::waveLoc1+Sea::sinArrayLength){
                //front of wave
                glBegin(GL_POLYGON);    
                glNormal3f(0.0f, 1.0f, 0.0f);   
                    glTexCoord2f(0.0, 1.0);glVertex3f(Sea::seaGrid[i][j].x, Sea::sinVals[nextK], Sea::seaGrid[i][j].z);
                    glTexCoord2f(0.0, 0.0);glVertex3f(Sea::seaGrid[i][j+1].x, Sea::sinVals[nextK], Sea::seaGrid[i][j+1].z);
                    glTexCoord2f(1.0, 0.0);glVertex3f(Sea::seaGrid[i+1][j+1].x, Sea::seaGrid[i+1][j+1].y , Sea::seaGrid[i+1][j+1].z);
                    glTexCoord2f(1.0, 1.0);glVertex3f(Sea::seaGrid[i+1][j].x, Sea::seaGrid[i+1][j].y, Sea::seaGrid[i+1][j].z);
                glEnd();
            }else{
                //rest of wave
                glBegin(GL_POLYGON);    
                glNormal3f(0.0f, 1.0f, 0.0f);   
                    glTexCoord2f(0.0, 1.0);glVertex3f(Sea::seaGrid[i][j].x, Sea::sinVals[k], Sea::seaGrid[i][j].z);
                    glTexCoord2f(0.0, 0.0);glVertex3f(Sea::seaGrid[i][j+1].x, Sea::sinVals[k], Sea::seaGrid[i][j+1].z);
                    glTexCoord2f(1.0, 0.0);glVertex3f(Sea::seaGrid[i+1][j+1].x, Sea::sinVals[nextK], Sea::seaGrid[i+1][j+1].z);
                    glTexCoord2f(1.0, 1.0);glVertex3f(Sea::seaGrid[i+1][j].x, Sea::sinVals[nextK], Sea::seaGrid[i+1][j].z);
                glEnd();
            }
        }else{
            //draw flat sea
            glBegin(GL_POLYGON);    
                glNormal3f(0.0f, 1.0f, 0.0f);
                glTexCoord2f(0.0, 1.0);glVertex3f(Sea::seaGrid[i+1][j].x, Sea::seaGrid[i+1][j].y, Sea::seaGrid[i+1][j].z);
                glTexCoord2f(0.0, 0.0);glVertex3f(Sea::seaGrid[i+1][j+1].x, Sea::seaGrid[i+1][j+1].y, Sea::seaGrid[i+1][j+1].z);
                glTexCoord2f(1.0, 0.0);glVertex3f(Sea::seaGrid[i][j+1].x, Sea::seaGrid[i][j+1].y, Sea::seaGrid[i][j+1].z);
                glTexCoord2f(1.0, 1.0);glVertex3f(Sea::seaGrid[i][j].x, Sea::seaGrid[i][j].y, Sea::seaGrid[i][j].z);
            glEnd();
        }
    }
    //increment k if i is in the area of the wave
    if(k < Sea::sinArrayLength-1 && (i >= Sea::waveLoc1 && i <= Sea::waveLoc1+Sea::sinArrayLength)){
        k++;
    }else if(k == Sea::sinArrayLength){
        k = 0;
    }
}
if(Sea::waveLoc1 < 100 && Sea::waveInc == Sea::waveSpeedLimiter){
    Sea::waveLoc1 +=1;
}else if(Sea::waveLoc1 >= 100){
    Sea::waveLoc1 = 0;
}
//limits speed of wave
if(Sea::waveInc < Sea::waveSpeedLimiter){
    Sea::waveInc++;
}else{
    Sea::waveInc = 0;
}

//disable texturing
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
glPopMatrix();

然后在我的display((函数中调用它,如下所示

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)screenWidth/(GLfloat)screenHeight,0.1f,1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
camera.updateCameraPosition(mouse_x,mouse_y,screenWidth,screenHeight);

sea.buildSeaPlane();
scene.buildEdges();

glPushMatrix(); 
glColor3f(0,1,0);
glTranslatef(0, 20, 200);
model.speedDisplayFaceNormals();
glPopMatrix();
glPushMatrix();
plane.updatePlanePosition();
glBegin(GL_POLYGON);    
    glNormal3f(0.0f, 1.0f, 0.0f);
    glVertex3f(0, 25, 10);
    glVertex3f(2, 25, 10);
    glVertex3f(2, 25, 20);
    glVertex3f(0, 25, 20);
glEnd();

glPopMatrix();
glFlush();  

你知道我为什么看不到这些吗?

更新:

如果我禁用纹理,我可以看到我的大海。如何修复它以便使用纹理和照明?

更新2:

已经将纹理更改为GL_MODULATE,但我也必须删除混合才能使其工作。我需要启用混合吗?

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

表示用纹理化的结果替换照明计算。如果希望照明影响纹理,请使用GL_MODULATE而不是GL_REPLACE

编辑以添加:

只有当您希望几何体是半透明的时,才需要混合(对于,混合通常是(。在您的情况下,代码中存在许多问题:

  • 你的浅色是完全透明的(所有颜色都有0。作为第四成分(。所以你的光让一切都看不见。将其更改为1
  • 你的材料没有第四个组成部分。更糟糕的是,glMaterialff预计会有4次浮动。这甚至可能使你的应用程序崩溃或重新格式化你的磁盘。添加第四组分,优选为1。以使其完全不透明

尝试为整个场景添加环境光。类似于:

GLfloat lightColor[] = {1.0f, 1.0f, 1.0f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lightColor);

glMaterialfv调用中,color参数应该有4个值,而不是3。通常情况下,第4个值是1.0的alpha。我也不确定传递0.0作为glLightfv的第四个值是否可以。

最新更新