opengldisplaylist

glPushMatrix inside display list duplicates models


I have a display list for some cubes... very simple stuff. Here's a snippet:

GL11.glPushMatrix
GL11.glRotatef(90,0,0,1)
cuboid(1,0.5,20) //just glVertex calls
GL11.glPopMatrix

If I use this to draw in immediate mode nothing odd happens. However if I put this in a display list it will first draw the cuboid unrotated and then rotated (or whatever transformation I do between glPushMatrix and glPopMatrix). Moreover, if I don't use glPush and glPop it behaves as expected.

Is there something I should need to know when using glPush/PopMatrix in display lists?

EDIT: adding some more source code:

handle = GL11.glGenLists(1);
GL11.glNewList(handle,GL11.GL_COMPILE)
GL11.glBegin(GL11.GL_LINES);

GL11.glPushMatrix //if I don't use these it behaves as expected
GL11.glRotatef(90,0,0,1)
cuboid(1,0.5,20) //just glVertex calls
GL11.glPopMatrix

GL11.glEnd();
GL11.glEndList();

EDIT2: I've made it works by swapping glBegin with glPushMatrix and glEnd with glPopMatrix - I don't like how it looks now but at least it works. From what I know this is NOT normal and what I've done is just a trick, so I'm leaving the question open.

GL11.glPushMatrix //everytime I want to push/pop I have to call glBegin and glEnd
GL11.glBegin(GL11.GL_LINES);
GL11.glRotatef(90,0,0,1)
cuboid(1,0.5,20) //just glVertex calls
GL11.glEnd();
GL11.glPopMatrix

Solution

  • It's an error to call glPushMatrix inside of glBegin/glEnd. There's only a strict subset of commands that can be used inside of a glBegin/glEnd pair.

    From glBegin man page:

    Only a subset of GL commands can be used between glBegin and glEnd. The commands are glVertex, glColor, glSecondaryColor, glIndex, glNormal, glFogCoord, glTexCoord, glMultiTexCoord, glVertexAttrib, glEvalCoord, glEvalPoint, glArrayElement, glMaterial, and glEdgeFlag. Also, it is acceptable to use glCallList or glCallLists to execute display lists that include only the preceding commands. If any other GL command is executed between glBegin and glEnd, the error flag is set and the command is ignored.

    On the man page for glPushMatrix:

    GL_INVALID_OPERATION is generated if glPushMatrix or glPopMatrix is executed between the execution of glBegin and the corresponding execution of glEnd.

    Start putting glGetError in your development code, it will point out these kinds of problems to you.

    Also glRotatef is not legal there either:

    GL_INVALID_OPERATION is generated if glRotate is executed between the execution of glBegin and the corresponding execution of glEnd.