2

I've been drawing Cornell box. I want to place light in my lamp(lamp is a white cube placed on the right wall). It will make an illusion that lamp is shining. But I can't place my light into the cube. I have tried to Set the view transform and then set light position, but it doesn't work. Here is my simple code: ( lamp cube has been moved glTranslatef(0.63, 0.3, 0.0))

 void display(void)
{

    glEnable(GL_DEPTH_TEST);
    glViewport(0, 0, 600, 600);
    glClearColor(0.32, 0.32, 0.32, 1);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    // draw cube
    glPushMatrix();
    glTranslatef(0.2, -0.3, 0.4);
    glColor3d(1.0, 0.38, 0.0);
    glutSolidCube(0.2);
    glPopMatrix();
    // draw sphere
    glPushMatrix();
    glTranslatef(0.2, -0.1, 0.4);
    glColor3d(0.71, 0.0, 0.59);
    glutSolidSphere(0.1,100,100);
    glPopMatrix();
    // draw parallelepiped
    glPushMatrix();
    glTranslatef(-0.2, -0.2, 0.25);
    glRotatef(20, 0.0, 1.0, 0.0);
    glColor3d(1.0, 0.38, 0.0);
    glScalef(1, 1.8, 1);
    glutSolidCube(0.2);
    glPopMatrix();
    // draw lamp
    glPushMatrix();
    glTranslatef(0.63, 0.3, 0.0);
    glScalef(1.5, 0.3, 1);
    glColor3d(1.0, 1.0, 1.0);
    glutSolidCube(0.2);
    glPopMatrix();

    glBegin(GL_QUADS);
    glNormal3f(0, 1.0, 0);
    glColor3d(0.69, 0.69, 0.69); // bottom
    glVertex3d(-0.5, -0.5, 0.5);
    glVertex3d(-0.5, -0.5, -0.5);
    glVertex3d(0.5, -0.5, -0.5);
    glVertex3d(0.5, -0.5, 0.5);
    glEnd();
    glBegin(GL_QUADS);
    glNormal3f(0, -1.0, 0);
    glColor3d(0.69, 0.69, 0.69); // top
    glVertex3d(-0.5, 0.5, 0.5);
    glVertex3d(-0.5, 0.5, -0.5);
    glVertex3d(0.5, 0.5, -0.5);
    glVertex3d(0.5, 0.5, 0.5);
    glEnd();
    glBegin(GL_QUADS);
    glNormal3f(-1.0, 0.0, 0.0);
    glColor3d(0.0, 0.79, 0.05); // right
    glVertex3d(0.5, -0.5, 0.5);
    glVertex3d(0.5, 0.5, 0.5);
    glVertex3d(0.5, 0.5, -0.5);
    glVertex3d(0.5, -0.5, -0.5);
    glEnd();
    glBegin(GL_QUADS);
    glNormal3f(1.0, 0.0, 0.0);
    glColor3d(1.0, 0.16, 0.0); // left
    glVertex3d(-0.5, -0.5, 0.5);
    glVertex3d(-0.5, 0.5, 0.5);
    glVertex3d(-0.5, 0.5, -0.5);
    glVertex3d(-0.5, -0.5, -0.5);
    glEnd();
    glBegin(GL_QUADS);
    glNormal3f(0.0, 0.0, 1.0);
    glColor3d(0.69, 0.69, 0.69); // back
    glVertex3d(-0.5, -0.5, -0.5);
    glVertex3d(-0.5, 0.5, -0.5);
    glVertex3d(0.5, 0.5, -0.5);
    glVertex3d(0.5, -0.5, -0.5);
    glEnd();
    glFlush();
    glPopMatrix();
    glutSwapBuffers();

}

void Initialize() {
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    GLfloat global_ambient[] = { 0.1, 0.1, 0.1, 1.0 };
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);
    GLfloat ambient[] = { 0.0,0.0,0.0,1.0 };
    GLfloat diffuse[] = { 1.0,1.0,1.0,1.0 };
    GLfloat spec[] = { 1,1,1,1 };
    GLfloat specref[] = { 1,1,1,1 };
    GLfloat lpos[] = { 0.0, 0.0, 0.0, 1.0 };
    glLightfv(GL_LIGHT0, GL_POSITION, lpos);
    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR, spec);

    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specref);
    glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 64);
    glEnable(GL_COLOR_MATERIAL);
    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
}

void exitFunc(unsigned char key, int x, int y) {
    switch (key) {
    case 27:
        exit(0);
        break;
    }
}

void reshape(int w, int h)
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-0.35, 0.35, -0.35, 0.35, 1.2, 400.0);
    glMatrixMode(GL_MODELVIEW);
    glTranslatef(0, 0, -2);
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(600, 600);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("Cornell Box");
    Initialize();
    glutDisplayFunc(display);
    glutKeyboardFunc(exitFunc);
    glutReshapeFunc(reshape);
    glutIdleFunc(display);

    glutMainLoop();
    return 0;   
}
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
V.Jakob
  • 35
  • 3

1 Answers1

3

Note, that drawing by glBegin/glEnd sequences, the fixed function pipeline matrix stack and fixed function pipeline per vertex light model, is deprecated since decades. Read about Fixed Function Pipeline and see Vertex Specification and Shader for a state of the art way of rendering.


Anyway, when the light position is set by glLightfv(GL_LIGHT0, GL_POSITION, pos), then pos is multiplied by the current model view matrix.
This means if the position is set before the model view matrix is set, then the light position is placed in absolut coordinates to the world.
If it is set after the model view matrix was set, then the light position can be set in the coordinate system of the model.

Set the light position when you draw the lamp, to the center of the "lamp":

// draw lamp
glPushMatrix();
glTranslatef(0.63, 0.3, 0.0);
glScalef(1.5, 0.3, 1);

GLfloat lpos[] = { 0.0, 0.0, 0.0, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, lpos);

glColor3d(1.0, 1.0, 1.0);
glutSolidCube(0.2);
glPopMatrix(); 

The OpenGL fixed function pipeline calculates the light per vertex: Gouraud shading.
This may cause, that you can't "see" the light, if the light vector hits the vertex coordinate by a acute angle relative to the plane of the surface.

In your case the green wall is almost unlit, because the light source is almost directly on the wall. The lam itself is not lit, because the light source is inside the lamp and it is light from the backside.

See OpenGL Lighting on texture plane is not working

Change the light position slightly, to put it in front of the wall, and tessellate the right wall to 4 quads, to "see" what I mean:

 GLfloat lpos[] = { -0.1, 0.0, 0.0, 1.0 }; 

// right
glBegin(GL_QUADS);
glNormal3f(-1.0, 0.0, 0.0);
glColor3d(0.0, 0.79, 0.05); 
glVertex3d(0.5,  0.3,  0.5);
glVertex3d(0.5,  0.5,  0.5);
glVertex3d(0.5,  0.5,  0.0);
glVertex3d(0.5,  0.3,  0.0);

glVertex3d(0.5,  0.3,  0.0);
glVertex3d(0.5,  0.5,  0.0);
glVertex3d(0.5,  0.5, -0.5);
glVertex3d(0.5,  0.3, -0.5);

glVertex3d(0.5, -0.5,  0.5);
glVertex3d(0.5,  0.3,  0.5);
glVertex3d(0.5,  0.3,  0.0);
glVertex3d(0.5, -0.5,  0.0);

glVertex3d(0.5, -0.5,  0.0);
glVertex3d(0.5,  0.3,  0.0);
glVertex3d(0.5,  0.3, -0.5);
glVertex3d(0.5, -0.5, -0.5);

glEnd();
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • thank you! I understand my mistake with coordinates, but I have a question. Please, look: https://ibb.co/jxDkk0 . I want that lamp should be white (because of the light), to do this, I should splits the quad into tiles, yes? – V.Jakob Nov 03 '18 at 09:16
  • I set `lpos[] = { -0.5, 0.0, 0.0, 1.0 };` but now the highlight on the sphere is on the left, it seems that the light source is shining from the left side. Please, look: https://ibb.co/ihXLk0 – V.Jakob Nov 03 '18 at 09:34
  • 1
    @V.Jakob Yes of course, this is not a fix, this should demonstrate the behavior. **You can*t fix it like that**. The easiest way to fix would be to get rid of the deprecated fixed function pipeline and to write a modern light model shader. – Rabbid76 Nov 03 '18 at 09:40
  • I uderstand, but I have a task to do it with GLUT :(. Thank you for all your advices. I was trying to do it in Modern OpenGL but it's too difficult to draw sphere in modern opengl, I don't know how. If you tell me how, I will be very grateful!!! For the future: Will be it possible to make shadows in Cornell box with shadow map (here, with GLUT)? – V.Jakob Nov 03 '18 at 09:50
  • 1
    @V.Jakob [GLUT](https://www.opengl.org/resources/libraries/glut/) API is for creating windows like [GLFW](https://www.glfw.org/). Of course you can use "modern" OpenGL with GLUT. I recommend to use [GLEW](http://glew.sourceforge.net/) for the OpenGL extensions and [GLM - OpenGL Mathematics](https://glm.g-truc.net/0.9.9/index.html) for the matrix operations. See [Sphere Calculations](https://stackoverflow.com/questions/49080505/sphere-calculations/49081855#49081855) for creating a sphere. – Rabbid76 Nov 03 '18 at 09:58