OpenGL 光照问题

发布于 2024-12-18 07:42:44 字数 5422 浏览 3 评论 0原文

当我在 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,但我还必须删除混合才能使其正常工作。我需要启用混合吗?

I'm having trouble being able to see objects I've created when I have enabled lighting in OpenGL. I have an object that is imported from 3D Max that the lighting works correctly on but the rest of my scene does not. I know that I need to specify normals but this hasn't seemed to have helped. Although if I create a simple polygon in my display() function that works correctly but other polygons that have been created in methods of a class and called in the display() function are not showing up

Here is my lighting code

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

This is my class method that is creating my sea

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

This is then called in my display() function as below

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

Any idea why I can't see any of this?

UPDATE:

I can see my sea if I disable texturing. How can I fix it so I can use textures and lighting?

UPDATE 2:

Have changed texturing to GL_MODULATE but I also had to remove the blending to make it work. Do I need blending enabled?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

や三分注定 2024-12-25 07:42:44
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

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

编辑添加

仅当您希望几何体半透明时才需要混合(这就是混合的典型用途)。就您而言,代码中存在许多问题:

  • 您的浅色是完全透明的(全部都有 0. 作为第四个分量)。所以你的光让一切都变得不可见。将其更改为 1。
  • 您的材料没有第四种成分。情况更糟,因为 glMaterialfv 需要 4 个浮点数。这甚至可能使您的应用程序崩溃或重新格式化您的磁盘。添加第四种成分,最好添加到 1. 中,使其完全不透明。
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

says to replace the lighting computation with the result of texturing. If you want lighting to affect texturing, us GL_MODULATE instead of GL_REPLACE.

Edit to add:

You only need blending if you want your geometry to be translucent (that's what blending is typically for). In your case, there are a number of issues in the code:

  • your light colors are fully transparent (all have 0. as the 4th component). So your light is making everything invisible. change it to 1.
  • your materials don't have a 4th component. That's even worse, as glMaterialfv expects 4 floats. That could even crash your app or reformat your disk. Add a forth component, preferably to 1. to make it fully opaque.
酷炫老祖宗 2024-12-25 07:42:44

尝试为整个场景添加环境光。像这样的东西:

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

Try adding an ambient light for the whole scene. Something like:

GLfloat lightColor[] = {1.0f, 1.0f, 1.0f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lightColor);
不乱于心 2024-12-25 07:42:44

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

In your glMaterialfv calls, the color parameter should have 4 values, not 3. Normally the 4th value is an alpha of 1.0. I'm not sure if it's OK to pass 0.0 as the 4th value for glLightfv either.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文