OpenGL Lines被其他对象隐藏

时间:2015-04-21 17:35:01

标签: c++ c opengl depth-buffer depth-testing

我的OpenGL程序出现问题。我绘制了三个轴Ox,Oy和Oz,以及位于轴上的4个金字塔。当我旋转形状时,轴应该是可见的,但它们被四个三角形隐藏。我该怎么做才能看到轴?

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

这是结果 enter image description here

虽然它应该是这样的 enter image description here

3 个答案:

答案 0 :(得分:1)

你可以删除 glEnable(GL_DEPTH_TEST)

有关深度缓冲的更多信息:https://www.opengl.org/wiki/Depth_Buffer

答案 1 :(得分:1)

我不认为你在答案中提到的解决方案有效;你可能改变了别的东西,并没有意识到它有效果。这是显示功能的更好的工作版本:

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. 正如您已经想到的那样,请务必将GLUT_DEPTH提供给显示模式。
  2. 确保金字塔的深度测试正在进行
  3. 确保线路关闭
  4. 在金字塔之后绘制行,以便在它们上面绘制它们。如果没有深度测试,事情就会按照他们发送的顺序一个接一个地绘制。
  5. 对于奖励积分,我重新排列了金字塔的顶点顺序,因此它始终是CCW。现在如果你做glEnable(GL_CULL_FACE),你只会从外面看到金字塔。
  6. 未能将GLUT_DEPTHglEnable(GL_DEPTH_TEST)用于金字塔将导致按顺序绘制边,这将是奇怪的和非物理的。

答案 2 :(得分:0)

我已将 glEnable(GL_DEPTH_TEST); 功能从 init()功能移至 main(),从而改变了我的代码像这样的功能

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

然后,程序像我预期的那样工作。我不知道为什么会这样。但是,感谢您的帮助。