C++ OpenGL线被其他对象隐藏

C++ OpenGL线被其他对象隐藏,c++,c,opengl,depth-buffer,depth-testing,C++,C,Opengl,Depth Buffer,Depth Testing,我的OpenGL程序有问题。我画了三个轴——牛、Oy和Oz,以及轴上的四个金字塔。当我旋转形状时,轴应该是可见的,但它们被四个三角形隐藏。我该怎么做才能看到轴 #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

我的OpenGL程序有问题。我画了三个轴——牛、Oy和Oz,以及轴上的四个金字塔。当我旋转形状时,轴应该是可见的,但它们被四个三角形隐藏。我该怎么做才能看到轴

#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;
}
#包括
#包括
#包括
#包括
使用名称空间std;
浮动x_角、y_角、z_角;
void init(){
x_角度=y_角度=z_角度=0;
glClearColor(0.0,0.0,0.0,0.0);
glEnable(GLU深度试验);
}
无效颜色3F(GLfloat红色、GLfloat绿色、GLfloat蓝色){
glColor3f(红色/255、绿色/255、蓝色/255);
}
无效绘制线(GLfloat x1、GLfloat y1、GLfloat z1、GLfloat x2、GLfloat y2、GLfloat z2、GLfloat红色、GLfloat绿色、GLfloat蓝色){
颜色3F(红色、绿色、蓝色);
glBegin(GL_行);
glVertex3f(x1,y1,z1);
glVertex3f(x2,y2,z2);
格伦德();
}
空心拉伸三角形(GLfloat x1、GLfloat y1、GLfloat z1、GLfloat x2、GLfloat y2、GLfloat z2、GLfloat x3、GLfloat y3、GLfloat z3、GLfloat红色、GLfloat绿色、GLfloat蓝色){
颜色3F(红色、绿色、蓝色);
glBegin(GL_三角形);
glVertex3f(x1,y1,z1);
glVertex3f(x2,y2,z2);
glVertex3f(x3,y3,z3);
格伦德();
}
{
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
glMatrixMode(GLU模型视图);
glLoadIdentity();
gluLookAt(5.0,5.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);
glMatrixMode(GL_投影);
glLoadIdentity();
格洛托(-15.0,15.0,-15.0,15.0,-15.0,15.0);
glViewport(100100500500);
glRotatef(x_角,1.0,0.0,0.0);
glRotatef(y_角,0.0,1.0,0.0);
glRotatef(z_角,0.0,0.0,1.0);
glPointSize(10.0);
抽绳(-10.0,0.0,0.0,10.0,0.0,0.0,255.0,0.0,0.0,0.0);
抽绳(0.0,-10.0,0.0,0.0,10.0,0.0,0.0,255.0,0.0);
抽绳(0.0,0.0,-10.0,0.0,0.0,10.0,0.0,0.0,255.0);
//画金字塔
drawTriangle(0.0,5.0,0.0,5.0,0.0,0.0,0.0,0.0,5.0,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(无符号字符键,int a,int b){
开关(钥匙){
案例“x”:
x_角-=3;
打破
案例“X”:
x_角+=3;
打破
案例“y”:
y_角-=3;
打破
案例“Y”:
y_角+=3;
打破
案例“z”:
z_角-=3;
打破
案例“Z”:
z_角+=3;
打破
违约:
打破
}
显示();
}
int main(int argv,字符**argc){
glutInit(&argv,argc);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
位置(100100);
glutInitWindowSize(800800);
创建窗口(“3D程序”);
init();
键盘功能(按ON键);
glutDisplayFunc(显示器);
glutMainLoop();
返回0;
}
这就是结果

而应该是这样

您可以通过卸下
glEnable(GL\U深度测试)


有关深度缓冲区的更多信息:

我已通过移动函数glEnable(GL\u DEPTH\u 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;
}

然后,这个项目像我预期的那样运作。我不知道为什么会这样。不过,感谢您的帮助。

我认为您在回答中提到的修复方案不起作用;你可能改变了一些别的东西,但没有意识到它有影响。下面是一个更好的显示功能工作版本:

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();
}
  • 正如您已经了解的,请确保为显示模式提供
    GLUT\u DEPTH
  • 确保金字塔的深度测试已打开
  • 一定要把它关上
  • 在金字塔后面画线,这样它们就会被画在金字塔的顶部。没有深度测试,事情只是按照发送顺序一个接一个地画出来
  • 为了获得额外的积分,我重新排列了金字塔的顶点顺序,使其始终保持逆时针方向。现在如果你做了
    glEnable(GL_CULL_FACE)
    你只能从外面看到金字塔

  • 未能为棱锥体使用
    GLUT\u DEPTH
    glEnable(GL\u DEPTH\u TEST)
    将导致按顺序绘制边,这将是奇异的和非物理的。

    在禁用深度测试的情况下最后绘制?我是OpenGL新手,所以我需要做什么?您还需要确保帧缓冲区具有深度缓冲区。您必须通过
    glutInitDisplayMode()
    处的
    GLUT\u DEPTH
    标志请求,如果不进行深度测试,金字塔将无法在所有情况下正确绘制,因此无法始终关闭。