Проблемы с освещением OpenGL - PullRequest
4 голосов
/ 25 ноября 2011

У меня проблемы с возможностью видеть объекты, которые я создал, когда я включил освещение в OpenGL.У меня есть объект, импортированный из 3D Max, на котором освещение работает правильно, но остальная часть моей сцены - нет.Я знаю, что мне нужно указать нормали, но это, похоже, не помогло.Хотя если я создаю простой многоугольник в моей функции display (), который работает правильно, но другие многоугольники, созданные в методах класса и вызываемые в функции display (), не отображаются

Вот мое освещение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);

Это мой метод класса, который создает мое море

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, но мне также пришлось удалить смешение, чтобы сделать егоРабота.Нужно ли включать смешивание?

Ответы [ 3 ]

2 голосов
/ 25 ноября 2011
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

говорит о необходимости заменить вычисление освещения на результат текстурирования.Если вы хотите, чтобы освещение влияло на текстурирование, используйте GL_MODULATE вместо GL_REPLACE.

Изменить, чтобы добавить:

Вам нужно только смешивать, если вы хотите, чтобы ваша геометриябыть полупрозрачным (это то, что смешивание обычно для ).В вашем случае в коде есть ряд проблем:

  • ваши светлые цвета полностью прозрачны (все имеют 0. как 4-й компонент).Итак, твой свет делает все невидимым.измените его на 1.
  • ваши материалы не имеют 4-й компонент.Это еще хуже, так как glMaterialfv ожидает 4 поплавка.Это может даже вывести из строя ваше приложение или переформатировать диск.Добавьте четвертый компонент, предпочтительно к 1., чтобы сделать его полностью непрозрачным.
0 голосов
/ 25 ноября 2011

В ваших glMaterialfv вызовах параметр цвета должен иметь 4 значения, а не 3. Обычно 4-е значение - это альфа, равный 1,0.Я не уверен, можно ли передать 0.0 как 4-е значение для glLightfv.

0 голосов
/ 25 ноября 2011

Попробуйте добавить рассеянный свет для всей сцены.Что-то вроде:

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