Search code examples
c++opengl3dglutfreeglut

Opengl lighting not working


So far a sky box and cube and ability to move the camera left right forward and back is working. However the cube is not being shaded by the lighting and isn't even appearing as the correct color. From my perspective I've enabled everything I was told to enable and created a light source etc etc so I'm pretty lost.

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

#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;
}

Solution

  • So, you draw this "temple" cube

    1. while texturing is still on, with the last texture of your skybox which is still bound. Since glutSloidCube does not provide any texcoords, the same texcoords will be used all over the place. You can use glDisable(GL_TEXTURE_2D) to disable it.
    2. with a color of (0,0,0) while glColorMaterial is set to GL_AMBIENT_AND_DIFFUSE, so you basically will get only specular lighting
    3. with the GL's fixed function, so you only get gouraud shading, and will not get any useful specular highlight because the lighting is just calculated at each corner vertex of your cube

    So, in the end, you'll get a crappy specular highlight, modulated by some corner texel color of some of on of your skybox textures, interpolated across your cube faces.

    You should note that almost every single GL function you are using is deprecated since a decade now. Your code is totally outdated, the fixed function is long gone from GPUs. If you really want to learn OpenGL nowadays, you shouldn't do it in ways which are 20 years old.