2

I'm having a trouble with my OpenGL program. I draw three axis Ox, Oy and Oz, along with 4 pyramids lying on the axis. When I rotate the shapes, the axis should be visible, but they are hidden by the four triangles. What can I do to see the axis?

#include <iostream>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

using namespace std;

float x_angle, y_angle, z_angle;

void init() {

    x_angle = y_angle = z_angle = 0;

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

}

void color3f(GLfloat red, GLfloat green, GLfloat blue) {
    glColor3f(red / 255, green / 255, blue / 255);
}

void drawLine(GLfloat x1, GLfloat y1, GLfloat z1, GLfloat x2, GLfloat y2, GLfloat z2, GLfloat red, GLfloat green, GLfloat blue) {

    color3f(red, green, blue);
    glBegin(GL_LINES);
    glVertex3f(x1, y1, z1);
    glVertex3f(x2, y2, z2);
    glEnd();

}

void drawTriangle(GLfloat x1, GLfloat y1, GLfloat z1, GLfloat x2, GLfloat y2, GLfloat z2, GLfloat x3, GLfloat y3, GLfloat z3, GLfloat red, GLfloat green, GLfloat blue) {

    color3f(red, green, blue);
    glBegin(GL_TRIANGLES);
    glVertex3f(x1, y1, z1);
    glVertex3f(x2, y2, z2);
    glVertex3f(x3, y3, z3);
    glEnd();
}

{

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(5.0, 5.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-15.0, 15.0, -15.0, 15.0, -15.0, 15.0);
    glViewport(100, 100, 500, 500);

    glRotatef(x_angle, 1.0, 0.0, 0.0);
    glRotatef(y_angle, 0.0, 1.0, 0.0);
    glRotatef(z_angle, 0.0, 0.0, 1.0);

    glPointSize(10.0);
    drawLine(-10.0, 0.0, 0.0, 10.0, 0.0, 0.0, 255.0, 0.0, 0.0);
    drawLine(0.0, -10.0, 0.0, 0.0, 10.0, 0.0, 0.0, 255.0, 0.0);
    drawLine(0.0, 0.0, -10.0, 0.0, 0.0, 10.0, 0.0, 0.0, 255.0);

    // draw pyramid
    drawTriangle(0.0, 5.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 5.0, 255, 255, 255);
    drawTriangle(0.0, 5.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, -5.0, 0, 255, 204);
    drawTriangle(0.0, 5.0, 0.0, -5.0, 0.0, 0.0, 0.0, 0.0, -5.0, 102, 102, 255);
    drawTriangle(0.0, 5.0, 0.0, -5.0, 0.0, 0.0, 0.0, 0.0, 5.0, 255, 255, 0);
    glFlush();
}

void onKeyPressed(unsigned char key, int a, int b) {
    switch (key) {
    case 'x':
        x_angle -= 3;
        break;
    case 'X':
        x_angle += 3;
        break;
    case 'y':
        y_angle -= 3;
        break;
    case 'Y':
        y_angle += 3;
        break;
    case 'z':
        z_angle -= 3;
        break;
    case 'Z':
        z_angle += 3;
        break;
    default:
        break;
    }

    display();
}


int main(int argv, char** argc) {

    glutInit(&argv, argc);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(800, 800);
    glutCreateWindow("3D program");

    init();
    glutKeyboardFunc(onKeyPressed);
    glutDisplayFunc(display);
    glutMainLoop();

    return 0;
}

This is the result enter image description here

while it should be like this enter image description here

The Dark Knight
  • 383
  • 1
  • 10
  • 21

3 Answers3

1

You can by removing the glEnable(GL_DEPTH_TEST)

more information about DEPTH BUFFER: https://www.opengl.org/wiki/Depth_Buffer

pepegasca
  • 74
  • 4
  • You also need to make sure that your framebuffer has a depth buffer. You have to request it via the `GLUT_DEPTH` flag at `glutInitDisplayMode()` – derhass Apr 21 '15 at 20:40
  • The pyramid won't be drawn correctly in all situations without depth testing, so it can't be turned off the entire time. – Jay Kominek Apr 22 '15 at 17:46
1

I don't think the fix you mentioned in your answer works; you probably changed something else and didn't realize it had an effect. Here's a better, working version of your display function:

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnable(GL_DEPTH_TEST);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(5.0, 5.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-15.0, 15.0, -15.0, 15.0, -15.0, 15.0);
    glViewport(100, 100, 500, 500);

    glRotatef(x_angle, 1.0, 0.0, 0.0);
    glRotatef(y_angle, 0.0, 1.0, 0.0);
    glRotatef(z_angle, 0.0, 0.0, 1.0);

    // draw pyramid
    drawTriangle(0.0, 5.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 5.0, 255, 255, 255);
    drawTriangle(0.0, 5.0, 0.0, 0.0, 0.0, -5.0, 5.0, 0.0, 0.0, 0, 255, 204);
    drawTriangle(0.0, 5.0, 0.0, -5.0, 0.0, 0.0, 0.0, 0.0, -5.0, 102, 102, 255);
    drawTriangle(0.0, 5.0, 0.0, 0.0, 0.0, 5.0, -5.0, 0.0, 0.0, 255, 255, 0);

    glDisable(GL_DEPTH_TEST);
    glPointSize(10.0);
    drawLine(-10.0, 0.0, 0.0, 10.0, 0.0, 0.0, 255.0, 0.0, 0.0);
    drawLine(0.0, -10.0, 0.0, 0.0, 10.0, 0.0, 0.0, 255.0, 0.0);
    drawLine(0.0, 0.0, -10.0, 0.0, 0.0, 10.0, 0.0, 0.0, 255.0);

    glFlush();
}
  1. As you've already figured out, make sure you supply GLUT_DEPTH to the display mode.
  2. Make sure depth testing is on for the pyramid
  3. Make sure it is off for the lines
  4. Draw the lines after the pyramid, so that they'll be drawn on top of it. Without depth testing, things are just drawn one on top of another, in the order they're sent.
  5. For bonus points, I rearranged the vertex order of your pyramid, so that it is all consistently CCW. Now if you do glEnable(GL_CULL_FACE) you'll only see the pyramid from the outside.

Failure to use GLUT_DEPTH and glEnable(GL_DEPTH_TEST) for the pyramid will result in the sides being drawn in order, which will be bizarre and non-physical.

Jay Kominek
  • 8,674
  • 1
  • 34
  • 51
0

I've changed my code by moving the function glEnable(GL_DEPTH_TEST); from init() function to main() function like this

int main(int argv, char** argc) {

glutInit(&argv, argc);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowPosition(100, 100);
glutInitWindowSize(800, 800);
glutCreateWindow("3D program");
glEnable(GL_DEPTH_TEST);

glutKeyboardFunc(onKeyPressed);
glutDisplayFunc(display);
glutMainLoop();

init();

return 0;
}

Then, the program worked like I expected. I don't know why this works. However, thanks for your helps.

The Dark Knight
  • 383
  • 1
  • 10
  • 21