2

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

这是结果 在此处输入图像描述

虽然它应该是这样的 在此处输入图像描述

4

3 回答 3

1

您可以通过删除 glEnable(GL_DEPTH_TEST)

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

于 2015-04-21T17:41:56.130 回答
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),你只会从外面看到金字塔。

不使用GLUT_DEPTHglEnable(GL_DEPTH_TEST)用于金字塔将导致边按顺序绘制,这将是奇怪的和非物理的。

于 2015-04-22T16:39:13.453 回答
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;
}

然后,该程序按我预期的那样运行。我不知道为什么会这样。不过,感谢您的帮助。

于 2015-04-22T16:22:13.420 回答