1

我不知道为什么当我运行此代码并使用菜单时,我在屏幕上看不到任何形状。当我用 glu[insertshape] 和相同的参数替换 glCallLists 行时,它可以完美运行,但代码行完全相同,但这次通过显示列表调用它并不起作用。

我什至使用打印语句进行检查,代码肯定正在运行

任何人都可以帮忙吗?

#include <GL/freeglut.h>
#include <GL/gl.h>
#include <cstdio>


GLUquadricObj* ptrSphere;
GLUquadricObj* ptrCylinder;
GLUquadricObj* ptrDisk;
GLUquadricObj* ptrPartDisk;

GLuint sphereListID;
GLuint cylinderListID;
GLuint diskListID;
GLuint partialDiskListID;

GLuint menuID;

GLuint currentListID;

void drawSphere()
{
    gluSphere(ptrSphere, 2, 25, 25);
    printf("sphere");
}

void drawCylinder()
{
    gluCylinder(ptrCylinder, 3, 3, 4, 25, 25);
    printf("cylinder");
}

void drawDisk()
{
    gluDisk(ptrDisk, 1.5, 3, 25, 25);
    printf("disk");
}

void drawPartDisk()
{
    gluPartialDisk(ptrPartDisk, 1.5, 3, 25, 25, 0, 90);
    printf("part disk");
}

void initQuadrics()
{
    ptrSphere = gluNewQuadric();
    gluQuadricDrawStyle(ptrSphere, GLU_LINE);
    ptrCylinder = gluNewQuadric();
    gluQuadricDrawStyle(ptrCylinder, GLU_LINE);
    ptrDisk = gluNewQuadric();
    gluQuadricDrawStyle(ptrDisk, GLU_LINE);
    ptrPartDisk = gluNewQuadric();
    gluQuadricDrawStyle(ptrPartDisk, GLU_LINE); 
}

void initLists()
{
    sphereListID = glGenLists(0);
    cylinderListID = glGenLists(0);
    diskListID = glGenLists(0);
    partialDiskListID = glGenLists(0);
    glNewList(sphereListID, GL_COMPILE);
        drawSphere();
    glEndList();
    glNewList(cylinderListID, GL_COMPILE);
        drawCylinder();
    glEndList();
    glNewList(diskListID, GL_COMPILE);
        drawDisk();
    glEndList();
    glNewList(partialDiskListID, GL_COMPILE);
        drawPartDisk();
    glEndList();
    currentListID = sphereListID;
}

void myMenu(int value)
{
    switch(value)
    {
        case(1):
        currentListID = sphereListID;
        break;
        case(2):
        currentListID = cylinderListID;
        break;
        case(3):
        currentListID = diskListID;
        break;
        case(4):
        currentListID = partialDiskListID;
        break;
    }
    glutPostRedisplay();
}

void initMenu()
{
    menuID = glutCreateMenu(myMenu);
    glutSetMenu(menuID);
    glutAddMenuEntry("Sphere", 1);
    glutAddMenuEntry("Cylinder", 2);
    glutAddMenuEntry("Disk", 3);
    glutAddMenuEntry("Partial Disk", 4);
    glutAttachMenu(GLUT_RIGHT_BUTTON);
}

void init()
{
    initQuadrics();
    initLists();
    initMenu();
}

void display()
{
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(1.0,1.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0);
    glClear(GL_COLOR_BUFFER_BIT);
    glCallList(currentListID);
    glutSwapBuffers();
}

void reshape(int w, int h)
{
    glViewport(0,0,w,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-4.0,4.0,-4.0,4.0,-4.0,4.0);
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(100,100);
    glutCreateWindow("OpenGL - First window demo");
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    init();
    glutMainLoop();
    return 0;
}
4

1 回答 1

3

我不确定这是否是 OPs 程序中唯一的问题,但它绝对是一个:

void initLists()
{
    sphereListID = glGenLists(0);
    cylinderListID = glGenLists(0);
    diskListID = glGenLists(0);
    partialDiskListID = glGenLists(0);

医生。glGenLists ()对此非常明确:

glGenLists有一个参数range。它返回一个整数n,以便创建名为 n, n + 1 , ... , n + range - 1 的范围连续的空显示列表。如果range为 0,如果没有可用的范围连续名称组,或者如果生成任何错误,则不生成显示列表,并返回 0。

(强调我的。)

所以,我会推荐:

  • 使用glGenLists(1)代替glGenLists(0)(或者甚至使用单个glGenLists(4)来一次生成所有列表 ID)。
  • 检查返回值glGenLists()是否不为 0。

在我们切换到 OpenGL 3+ 之前,我们使用显示列表来提高视觉模拟应用程序的性能。效果非常好(我们甚至很难在 OpenGL 3+ 中使用缓冲区和着色器获得相同的性能)。

使用显示列表仍然适用于最近的专业(昂贵)显卡。在(便宜得多的)消费类显卡上,我们注意到旧代码的性能下降令人不满意,而仅使用 OpenGL 3+ 函数时我们实现了可比的性能。

于 2020-09-24T06:22:01.910 回答