GLU quadrics in display lists?

161 views Asked by At

I have no idea why when i run this code and use the menu i do not see any of the shapes on the screen. When i replace the glCallLists line with a glu[insertshape] and the same parameters it works perfectly but the exact same line of code but this time called through a display list and it doesn't work.

Ive even used print statements to check and the code is definitely being run

Can anyone help?

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

There are 1 answers

1
Scheff's Cat On

I'm not sure whether this is the only issue in OPs program but it's definitely one:

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

The doc. of glGenLists() is quite explicit about this:

glGenLists has one argument, range. It returns an integer n such that range contiguous empty display lists, named n, n + 1 , ... , n + range - 1 , are created. If range is 0, if there is no group of range contiguous names available, or if any error is generated, no display lists are generated, and 0 is returned.

(Emphasize mine.)

So, I would recommend:

  • Use glGenLists(1) instead of glGenLists(0) (or even use a single glGenLists(4) to generate all list IDs at once).
  • Check that the return value of glGenLists() is not 0.

Before we switched to OpenGL 3+, we used display lists to improve the performance in our Visual Simulation applications. That worked amazingly well (and we even had difficulties to gain the same performance in OpenGL 3+ using buffers and shaders).

Using display lists still works well with recent professional (expensive) graphics cards. On (much cheaper) consumer graphics cards, we noticed an unsatisfying performance drop with our legacy code while we achieve comparable performance when we use OpenGL 3+ functions only.