Search code examples
openglperspectiveglfrustum

Perspective drawing in OpenGL using glFrustum


I'm trying to draw a cube in cabinet perspective. This is the cube in glOrtho:

cube

Other faces: Back - cyan, Left - magenta, down - blue

This is what I get

This is what I want to achieve

My code:

//init function
glClearColor(1, 1, 1, 1);

glEnable(GL_DEPTH_TEST);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-10, 10, -10, 10, 4,6);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslated(0,0,-lat);//it doesn't show in the window without this.
DisplayAxis();
DisplayObject();
break;
//object initalization. I use glGenList and glCallList to draw it
void InitObject() {
    glNewList(k, GL_COMPILE);

    glColor3f(1, 0, 0); 
    glBegin(GL_QUADS);
    glVertex3d(0, lat, lat);
    glVertex3d(lat, lat, lat);
    glVertex3d(lat, 0, lat);
    glVertex3d(0, 0, lat);
    glEnd();

    glColor3f(1, 1, 0); 
    glBegin(GL_QUADS);
    glVertex3d(lat, 0, 0);
    glVertex3d(lat, 0, lat);
    glVertex3d(lat, lat, lat);
    glVertex3d(lat, lat, 0);
    glEnd();

    glColor3f(0, 1, 0); 
    glBegin(GL_QUADS);
    glVertex3d(0, lat, lat);
    glVertex3d(lat, lat, lat);
    glVertex3d(lat, lat, 0);
    glVertex3d(0, lat, 0);
    glEnd();

    glColor3f(0, 0, 1); 
    glBegin(GL_QUADS);
    glVertex3d(0, 0, 0);
    glVertex3d(lat, 0, 0);
    glVertex3d(lat, 0, lat);
    glVertex3d(0, 0, lat);
    glEnd();

    glColor3f(1, 0, 1);  
    glBegin(GL_QUADS);
    glVertex3d(0, 0, lat);
    glVertex3d(0, 0, 0);
    glVertex3d(0, lat, 0);
    glVertex3d(0, lat, lat);
    glEnd();

    glColor3f(0, 1, 1); 
    glBegin(GL_QUADS);
    glVertex3d(0, lat, 0);
    glVertex3d(lat, lat, 0);
    glVertex3d(lat, 0, 0);
    glVertex3d(0, 0, 0);
    glEnd();
    glEndList();
}

What am I doing wrong here? I tried some rotations on the object but I get some skewed results(I can post more images if needed).


Solution

  • The object is clipped by the near plane of the Viewing frustum.

    Not you have to translate the object along the negativ z axis, to move the object in between the near and far plane of the viewing frustum:

    glTranslated(0,0,-lat);//it doesn't show in the window without this.
    

    Since the view space z axis points out out the viewport, you have to shift the object along the negative z axis.
    The distance to the near plane is 4 and the distance to the far plane is 6:

    glFrustum(-10, 10, -10, 10, 4,6);
    

    The distance to the front of the cube is less than 4, thus it is clipped by the near plane.

    Change the frustum, and keep the cube completely in the frustum to solve the issue:

    glFrustum(-10, 10, -10, 10, 4,6);

    glFrustum(-2.5, 2.5, -2.5, 2.5, 1, 10);
    

    glTranslated(0,0,-lat);

    glTranslated(0, 0, -6);
    

    For a good perspective and look at the scene, use a projection matrix (frustum) with a smaller field of view:

    glFrustum(-1, 1, -1, 1, 1, 12);
    

    Alternatively you can define the frustum by gluPerspective and set the field of view angle in degrees:

    gluPerspective(90, 1, 1, 12);
    

    The view matrix defines the position and viewing direction of the observer (viewer) within the scene.

    If you want a different look at the scene the you have to rotate the scene (glRotate):

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslated(0, 0, -8);
    glRotatef(30, 1, 0, 0);
    glRotatef(-45, 0, 1, 0);
    

    Alternatively the look at the scene (view matrix) can be defined by gluLookAt . Arguments 1-3 are the position of the observer (x,y, z components of eye or camera position). The Arguments 4-6 are the target point (where the observer looks at). The arguments 7-9 are the upwards vector.

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(5, 5, 7, 0, 0, 0, 0, 1, 0);