Opengl照明无法正常工作

时间:2018-04-04 13:04:48

标签: c++ opengl 3d glut freeglut

到目前为止,天空盒和立方体以及向前和向后移动相机的能力正在发挥作用。但是,立方体不会被照明遮挡,甚至不会显示为正确的颜色。从我的角度来看,我已经启用了我被告知启用和创建光源等所有内容,所以我很丢失。

//  ========================================================================
//
//  ========================================================================

#include <iostream>
#include <GL/freeglut.h>
#include <cmath>
#include "loadTGA.h"
using namespace std;

#define GL_CLAMP_TO_EDGE 0x812F   //To get rid of seams between textures
float theta = 0.0;      //Camera rotation
float cdr=3.14159265/180.0; //Conversion from degrees to radians
float eye_x=0.0, eye_z=0.0; 
float look_x=eye_x + 100*sin(cdr*theta);
float look_z=eye_z - 100*cos(cdr*theta);

GLuint texId[6];

void loadGLTextures()               // Load bitmaps And Convert To Textures
{
    glGenTextures(6, texId);        // Create texture ids
    // *** left ***
    glBindTexture(GL_TEXTURE_2D, texId[0]);
    loadTGA("alps_rt.tga");
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);    
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);    

    // *** front ***
    glBindTexture(GL_TEXTURE_2D, texId[1]);
    loadTGA("alps_ft.tga");
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);    
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);    

    // *** right ***
    glBindTexture(GL_TEXTURE_2D, texId[2]);
    loadTGA("alps_lf.tga");
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);    
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);    

    // *** back***
    glBindTexture(GL_TEXTURE_2D, texId[3]);
    loadTGA("alps_bk.tga");
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);    
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);    

    // *** top ***
    glBindTexture(GL_TEXTURE_2D, texId[4]);
    loadTGA("alps_up.tga");
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);    
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);    

    // *** down ***
    glBindTexture(GL_TEXTURE_2D, texId[5]);
    loadTGA("grass.tga");
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);   
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
}

//========================================================================================

void temple(){


    glColor3f(0, 0, 0);
    glPushMatrix();
      glTranslatef(20, 10, 0);
      glutSolidCube(1);
    glPopMatrix();


}



void skybox(){
    glEnable(GL_TEXTURE_2D);

    ////////////////////// LEFT WALL ///////////////////////
    glBindTexture(GL_TEXTURE_2D, texId[0]);
    glBegin(GL_QUADS);
    glTexCoord2f(0., 0.);
    glVertex3f(-10000,  0, 10000);
    glTexCoord2f(1., 0.);
    glVertex3f(-10000, 0., -10000);
    glTexCoord2f(1., 1.);
    glVertex3f(-10000, 10000., -10000);
    glTexCoord2f(0., 1.);
    glVertex3f(-10000, 10000, 10000);
    glEnd();

    ////////////////////// FRONT WALL ///////////////////////
    glBindTexture(GL_TEXTURE_2D, texId[1]);
    glBegin(GL_QUADS);
    glTexCoord2f(0., 0.);
    glVertex3f(-10000,  0, -10000);
    glTexCoord2f(1., 0.);
    glVertex3f(10000, 0., -10000);
    glTexCoord2f(1., 1.);
    glVertex3f(10000, 10000, -10000);
    glTexCoord2f(0., 1.);
    glVertex3f(-10000,  10000, -10000);
    glEnd();

    ////////////////////// RIGHT WALL ///////////////////////
    glBindTexture(GL_TEXTURE_2D, texId[2]);
    glBegin(GL_QUADS);
    glTexCoord2f(0., 0.);
    glVertex3f(10000,  0, -10000);
    glTexCoord2f(1., 0.);
    glVertex3f(10000, 0, 10000);
    glTexCoord2f(1., 1.);
    glVertex3f(10000, 10000,  10000);
    glTexCoord2f(0., 1.);
    glVertex3f(10000,  10000,  -10000);
    glEnd();


    ////////////////////// REAR WALL ////////////////////////
    glBindTexture(GL_TEXTURE_2D, texId[3]);
    glBegin(GL_QUADS);
    glTexCoord2f(0., 0.);
    glVertex3f( 10000, 0, 10000);
    glTexCoord2f(1., 0.);
    glVertex3f(-10000, 0,  10000);
    glTexCoord2f(1., 1.);
    glVertex3f(-10000, 10000,  10000);
    glTexCoord2f(0., 1.);
    glVertex3f( 10000, 10000, 10000);
    glEnd();

    /////////////////////// TOP //////////////////////////
    glBindTexture(GL_TEXTURE_2D, texId[4]);
    glBegin(GL_QUADS);
    glTexCoord2f(0., 0.);
    glVertex3f(-10000, 10000, -10000);
    glTexCoord2f(1., 0.);
    glVertex3f(10000, 10000,  -10000);
    glTexCoord2f(1., 1.);
    glVertex3f(10000, 10000,  10000);
    glTexCoord2f(0., 1.);
    glVertex3f(-10000, 10000, 10000);
    glEnd();

    /////////////////////// FLOOR //////////////////////////
    glBindTexture(GL_TEXTURE_2D, texId[5]);
    glBegin(GL_QUADS);
    glTexCoord2f(0., 0.);
    glVertex3f(-10000, 0., 10000);
    glTexCoord2f(100., 0.);
    glVertex3f(10000, 0.,  10000);
    glTexCoord2f(100., 100.);
    glVertex3f(10000, 0., -10000);
    glTexCoord2f(0., 100.);
    glVertex3f(-10000, 0., -10000);
    glEnd();

}

//---------------------------------------------------------------------
void initialise(void) 
{    
    float grey[4] = {0.2, 0.2, 0.2, 1.0};
    float white[4]  = {1.0, 1.0, 1.0, 1.0};

    loadGLTextures();

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);

    glLightfv(GL_LIGHT0, GL_AMBIENT, grey);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, white);
    glLightfv(GL_LIGHT0, GL_SPECULAR, white);

    glEnable(GL_COLOR_MATERIAL);
    glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_NORMALIZE);
    glClearColor (0.0, 0.0, 0.0, 0.0);

    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluPerspective(90.0, 1.0, 1.0, 20000.0);   //Perspective projection

}

//---------------------------------------------------------------------
void display(void)
{
    float outsidelightpos[4] = {1.0f, 1.0f, 1.0f, 1.0f};

    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    gluLookAt (eye_x, 10, eye_z, look_x, 10, look_z, 0, 1, 0);  //camera rotation

    glLightfv(GL_LIGHT0, GL_POSITION, outsidelightpos);

    skybox();

    temple();

    glFlush();
}

//--------------------------------------------------------------
 void special(int key, int x, int y)
 {

    if(key==GLUT_KEY_LEFT) theta-=5;         //Turn left
    else if(key==GLUT_KEY_RIGHT) theta+=5;   //Turn right
    else if(key == GLUT_KEY_DOWN)
    {  //Move backward
        eye_x -= 5*sin(cdr*theta);
        eye_z += 5*cos(cdr*theta);
    }
    else if(key == GLUT_KEY_UP)
    { //Move forward
        eye_x += 5*sin(cdr*theta);
        eye_z -= 5*cos(cdr*theta);
    }

    look_x = eye_x + 100*sin(cdr*theta);
    look_z = eye_z - 100*cos(cdr*theta);

    glutPostRedisplay();
    glutSwapBuffers();
}
//-------------------------------------------------------------------

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode (GLUT_SINGLE | GLUT_DEPTH);
    glutInitWindowSize (1024, 800); 
    glutInitWindowPosition (50, 50);

    glutCreateWindow ("Alex Bull's Assignment");
    initialise();
    glutDisplayFunc(display); 
    glutSpecialFunc(special);

    glutMainLoop();
    return 0;
}

1 个答案:

答案 0 :(得分:1)

所以,你画这个“寺庙”立方体

  1. 当纹理仍然打开时,天空盒的最后一个纹理仍然是绑定的。由于glutSloidCube不提供任何texcoords,因此将在整个地方使用相同的texcoords。您可以使用glDisable(GL_TEXTURE_2D)将其停用。
  2. 的颜色为(0,0,0)而glColorMaterial设置为GL_AMBIENT_AND_DIFFUSE,因此您基本上只会获得高光照明
  3. 使用GL的固定功能,因此您只能获得gouraud阴影,并且不会获得任何有用的镜面反射高光,因为光照只是在您的立方体的每个角顶点处计算
  4. 所以,最后,你会得到一个蹩脚的镜面反射高光,由你的天空盒纹理中某些角落纹理颜色调制,在你的立方体面上进行插值。

    您应该注意,几乎每一个GL功能都是已弃用,因为现在十年。您的代码完全过时,固定功能早已从GPU中消失。如果你现在真的想学习OpenGL,你就不应该用20年的方式来学习。