0

首先我定义了一个结构来表达金字塔的坐标:

typedef struct
{
    GLfloat xUp;
    GLfloat yUp;
    GLfloat zUp;
    GLfloat base;
    GLfloat height;
}pyramid;

这里非常不言自明:我存储了最高点的坐标、底数和高度。
我写了一个绘制金字塔的函数:

void drawPyramid(pyramid pyr)
{
    GLfloat p1[]= {pyr.xUp+pyr.base/2.0, pyr.yUp-pyr.height, pyr.zUp-pyr.base/2.0};
    GLfloat p2[]= {pyr.xUp+pyr.base/2.0, pyr.yUp-pyr.height, pyr.zUp+pyr.base/2.0};
    GLfloat p3[]= {pyr.xUp-pyr.base/2.0, pyr.yUp-pyr.height, pyr.zUp+pyr.base/2.0};
    GLfloat p4[]= {pyr.xUp-pyr.base/2.0, pyr.yUp-pyr.height, pyr.zUp-pyr.base/2.0};
    GLfloat up[]= {pyr.xUp, pyr.yUp, pyr.zUp};

    glBegin(GL_TRIANGLES);

    glColor4f(1.0, 0.0, 0.0, 0.0);
    glVertex3fv(up);
    glVertex3fv(p1);
    glVertex3fv(p2);

    glColor4f(0.0, 1.0, 0.0, 0.0);
    glVertex3fv(up);
    glVertex3fv(p2);
    glVertex3fv(p3);

    glColor4f(0.0, 0.0, 1.0, 0.0);
    glVertex3fv(up);
    glVertex3fv(p3);
    glVertex3fv(p4);

    glColor4f(1.0, 1.0, 0.0, 0.0);
    glVertex3fv(up);
    glVertex3fv(p4);
    glVertex3fv(p1);
    glEnd();



    glColor4f(0.0, 1.0, 1.0, 0.0);
    glBegin(GL_QUADS);
    glVertex3fv(p1);
    glVertex3fv(p2);
    glVertex3fv(p3);
    glVertex3fv(p4);
    glEnd();

}

我努力按逆时针顺序绘制所有顶点,但可能我搞砸了。
这就是我在渲染函数中显示金字塔的方式:

void display()
{
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glTranslatef(0.0, -25.0, 50.0);
    glRotatef(-angle, 0.0, 1.0, 0.0);
    glTranslatef(0.0, 25.0, -50.0);

    pyramid pyr;
    pyr.xUp=0.0;
    pyr.yUp=10.0;
    pyr.zUp=50.0;
    pyr.base=10.0;
    pyr.height=18.0;
    glColor4f(1.0, 0.0, 0.0, 0.0);
    drawPyramid(pyr);

    glutSwapBuffers();
}

我还使用了在 glut 主循环之前调用的 init 方法:

void init()
{
    glEnable(GL_DEPTH);
    glViewport(-1.0, 1.0, -1.0, 1.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(35.0, 1.0, 1.0, 100.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0.0,1.0,0.0, 0.0,1.0,30.0, 0.0,1.0,0.0);
}

角度只是我用来旋转金字塔的两倍,可以通过按'r'来改变,但这不相关。看来真正的问题是我如何绘制顶点。
问题是金字塔的面看起来很分散,乱七八糟。我最好用一张图片来描述这种情况:

金字塔

有一张脸太小了,显示出来了,我不知道为什么。
如果我旋转金字塔,它看起来很乱,我什至录制了一段视频来描述这一点。
如果问题不完全清楚,稍后我可以上传它。

PS:很多人注意到我使用过时的技术。但不幸的是,这是我的大学提供的。

编辑

我忘了说主要功能:

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(500, 500);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("Sierpinsky Pyramid");
    glutDisplayFunc(display);
    glutKeyboardFunc(keyboard);
    init();
    glutMainLoop();
    return 0;
}
4

1 回答 1

3

看起来深度缓冲区没有初始化。

打电话glEnable(GL_DEPTH_TEST)是不够的。您必须正确初始化 glut 并指定您想要深度缓冲区支持,否则您将无法获得深度缓冲区。如果我没记错的话,这是使用glutInitDisplayMode(GLUT_DEPTH|...). 请参阅此处的文档和此处的介绍。可以使用 google 找到更多信息。

- 编辑 -

您将无效参数传递给 glEnable。调用glEnable(GL_DEPTH_TEST)而不是glEnable(GL_DEPTH).

还:

  1. 显示功能中的矩阵代码不受 glPushMatrix/glPopMatrix 保护。这意味着每次旋转金字塔时,都会将旋转应用于先前的变换。即调用显示函数将旋转金字塔。
  2. 使用无效参数调用 glViewport。glViewport 需要 4 个整数参数,但您正在尝试传递浮点数。另外,“-1.0的宽度”应该是什么意思?
  3. 您尚未检查任何错误代码 (glGetError)。如果您在 glEnable 调用后尝试调用 glGetError,那么您会看到它返回 GL_INVALID_ENUM。

OpenGL 有文档。文档可在 opengl.org 上找到。使用它并阅读它。另外,我建议阅读“OpenGL 红皮书”。

于 2012-11-18T17:07:10.963 回答