Search code examples
c++opengllighting

How to fix bitmap lighting in openGL?


I need help with my code in C++ using the OpenGL API. I have written a program that draws 4 3D cubes and text (using bitmap) onto the screen. Now I want to add lighting.

I have added glMaterial code to give a description of the material for the cubes. I do not want the material properties to be applied to the bitmap text. Therefore, I placed the code for the material before drawing the cube and I also placed the code for drawing the cube and the material between a pushMatrix and popMatrix pair. However, when I run the code, I find the text changes color.

Below is some of the code that I am using:

void init() {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ligAmb);
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lig[0][0]);
glLightfv(GL_LIGHT0, GL_SPECULAR, lig[0][1]);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, ligDir);
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, exp_one);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, cutoff);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT1, GL_DIFFUSE, lig[1][0]);
glLightfv(GL_LIGHT1, GL_SPECULAR, lig[1][1]);
glEnable(GL_LIGHT1);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

}

void drawCube(Point3D colors[], Point3D vertices[]) {
glBegin(GL_QUADS);
glColor3fv(colors[1]);
glVertex3fv(vertices[1]);
glColor3fv(colors[5]);
glVertex3fv(vertices[5]);
glColor3fv(colors[7]);
glVertex3fv(vertices[7]);
glColor3fv(colors[3]);
glVertex3fv(vertices[3]);
glColor3fv(colors[7]);
glVertex3fv(vertices[7]);
glColor3fv(colors[6]);
glVertex3fv(vertices[6]);
glColor3fv(colors[2]);
glVertex3fv(vertices[2]);
glColor3fv(colors[3]);
glVertex3fv(vertices[3]);
glColor3fv(colors[2]);
glVertex3fv(vertices[2]);
glColor3fv(colors[6]);
glVertex3fv(vertices[6]);
glColor3fv(colors[4]);
glVertex3fv(vertices[4]);
glColor3fv(colors[0]);
glVertex3fv(vertices[0]);

glColor3fv(colors[5]);
glVertex3fv(vertices[5]);
glColor3fv(colors[4]);
glVertex3fv(vertices[4]);
glColor3fv(colors[6]);
glVertex3fv(vertices[6]);
glColor3fv(colors[7]);
glVertex3fv(vertices[7]);

glColor3fv(colors[4]);
glVertex3fv(vertices[4]);
glColor3fv(colors[5]);
glVertex3fv(vertices[5]);
glColor3fv(colors[1]);
glVertex3fv(vertices[1]);
glColor3fv(colors[0]);
glVertex3fv(vertices[0]);

glColor3fv(colors[0]);
glVertex3fv(vertices[0]);
glColor3fv(colors[1]);
glVertex3fv(vertices[1]);
glColor3fv(colors[3]);
glVertex3fv(vertices[3]);
glColor3fv(colors[2]);
glVertex3fv(vertices[2]);
glEnd();



}

void displayObject() {

glPushMatrix();
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLightfv(GL_LIGHT0, GL_POSITION, ligPos[0]);

glLightfv(GL_LIGHT1, GL_POSITION, ligPos[1]);
typedef GLint vertex3[3];

Point3D vertices[8] = { {-1.0, -1.0, -1.0},
                {-1.0, -1.0,  1.0},
                {-1.0,  1.0, -1.0},
                {-1.0,  1.0,  1.0},
                { 1.0, -1.0, -1.0},
                { 1.0, -1.0,  1.0},
                { 1.0,  1.0, -1.0},
                { 1.0,  1.0,  1.0} };

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_INT, 0, vertices);
GLubyte vertIndex[] = { 6,2,3,7,5,1,0,4,7,3,1,5,4,0,2,6,2,0,1,3,7,5,4,6 
};

glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, vertIndex);
glPopMatrix();




Point3D colorsb[8] = { {0.,0.,1.},
                    {0.,0.,1.},
                    {0.,0.,1.},
                    {0.,0.,1.},
                    {0.,0.,1.},
                    {0.,0.,1.},
                    {0.,0.,1.},
                    {0.,0.,1.} };

Point3D colorsg[8] = { {0.,1.,0.},
                    {0.,1.,0.},
                    {0.,1.,0.},
                    {0.,1.,0.},
                    {0.,1.,0.},
                    {0.,1.,0.},
                    {0.,1.,0.},
                    {0.,1.,0.} };

Point3D colorsr[8] = { {1.,0.,0.},
                    {1.,0.,0.},
                    {1.,0.,0.},
                    {1.,0.,0.},
                    {1.,0.,0.},
                    {1.,0.,0.},
                    {1.,0.,0.},
                    {1.,0.,0.} };

Point3D colorsy[8] = { {1.,1.,0.},
                    {1.,1.,0.},
                    {1.,1.,0.},
                    {1.,1.,0.},
                    {1.,1.,0.},
                    {1.,1.,0.},
                    {1.,1.,0.},
                    {1.,1.,0.} };



glPushMatrix();

glTranslatef(-0.5f, 4.0f, -6.0f);
glRotatef(10.0, 0.0, 1.0, 0.0);
glRotatef(loop, 0.0, 1.0, 0.0);

glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat[0][0]);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat[0][1]);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat[0][2]);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shi[0]);

drawCube(colorsb, vertices);
glPopMatrix();

glPushMatrix();
glTranslatef(6.0f, -0.5f, -6.0f);
glRotatef(10.0, 1.0, 0.0, 0.0);
glRotatef(loop, 0.0, 1.0, 0.0);

glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat[1][0]);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat[1][1]);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat[1][2]);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shi[1]);
drawCube(colorsg, vertices);
glPopMatrix();

glPushMatrix();
glTranslatef(-0.5f, -4.5f, -6.0f);
glRotatef(10.0, 0.0, 1.0, 0.0);
glRotatef(loop, 0.0, 1.0, 0.0);

glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat[2][0]);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat[2][1]);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat[2][2]);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shi[2]);
drawCube(colorsr, vertices);
glPopMatrix();

glPushMatrix();
glTranslatef(-6.0f, -0.5f, -6.0f);
glRotatef(10.0, 1.0, 0.0, 0.0);
glRotatef(loop, 0.0, 1.0, 0.0);

glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat[3][0]);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat[3][1]);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat[3][2]);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shi[3]);
drawCube(colorsy, vertices);
glPopMatrix();
}




void display() {



    displayObject();


    wordColor = "green";
    char str[] = { "Red" };

    glColor3f(0.0, 1.0, 0.0);

    glRasterPos2f(-0.5, 0.0);

    for (int i = 0; i < strlen(str); i++)
    {

        glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, str[i]);
    }

    glPopMatrix();
    loop += 0.05;
    glFlush();
    glutSwapBuffers();

    glutPostRedisplay();

    }

Solution

  • OpenGL is a state machine, which means that it keeps a state around until you explicitly change it again. So when you take care to set the illumination only after drawing the text during drawing one frame, it will have happened before drawing the text of the next frame.

    The solution is, that you always set every relevant state for whatever it is you're drawing, right before you draw it. In case of the text, it's as simple as disable lighting, right before drawing the text (actually before calling glRasterPos).