Werewolve
Werewolve

Reputation: 2528

glPushMatrix() & glPopMatrix() throw GL_INVALID_OPERATION

i try to draw a waveform from the incoming iphone microphone stream. The extraction of the data was no problem an the drawing works fine. Only when I use the OpenGL Exception Breakpoint xcode throws exceptions at glPushMatrix() & glPopMatrix()with the code GL_INVALID_OPERATION. I searched the internet for some more informations, but the only thing that i found was this:

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

i dont use the commands glBegin oder glEnd, because of that this doesn't help me. Any ideas? What is the problem here? i draw the stuff like this:

- (void)drawPlotWithView:(GLKView*)view drawInRect:(CGRect)rect {

glBindBuffer(GL_ARRAY_BUFFER, _plotVBO);

glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(XOAudioPlotGLPoint), NULL);

[self.baseEffect prepareToDraw];
glPushMatrix();
self.baseEffect.transform.modelviewMatrix = GLKMatrix4MakeXRotation(0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, _plotGraphSize);
glPopMatrix();

[self.baseEffect prepareToDraw];
glPushMatrix();
self.baseEffect.transform.modelviewMatrix = GLKMatrix4MakeXRotation(M_PI);
glDrawArrays(GL_TRIANGLE_STRIP, 0, _plotGraphSize);
glPopMatrix();

glBindBuffer(GL_ARRAY_BUFFER, 0);
}

the initialization ist like this:

self.baseEffect = [[GLKBaseEffect alloc] init];
self.baseEffect.useConstantColor = GL_TRUE;
self.preferredFramesPerSecond = 60;


if (![EAGLContext currentContext]) {
    self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
} else {
    self.context = [EAGLContext currentContext];
}

if (!self.context) {
    NSLog(@"Failed to create ES context");
} else {
    EAGLContext.currentContext = self.context;
}

GLKView *view = (GLKView *)self.view;
view.context = self.context;
view.drawableMultisample = GLKViewDrawableMultisample4X;
glGenBuffers(1, &_plotVBO);
glLineWidth(2.0f);

Upvotes: 0

Views: 720

Answers (2)

Thomas
Thomas

Reputation: 725

Continuing my research on the topic, the answer seems to be that OpenGL ES 2.0 indeed does not support matrix stack or push/pop, see here.

Upvotes: 0

rickster
rickster

Reputation: 126127

glPushMatrix and glPopMatrix refer to the built-in matrix stack from the fixed-function OpenGL pipeline -- that functionality isn't in OpenGL ES 2.0.

However, the way that you're using it looks like it's not really doing anything, and what you are doing is in the wrong order. Drawing with GLKBaseEffect takes three steps:

  1. Set the modelview and projection matrices via properties on your GLKBaseEffect instance. There's no "current matrix" or "matrix mode" implicit state like there is in GLES 1.x; just explicitly named and separately stored properties on GLKBaseEffect. (You're already doing this with the lines where you set self.baseEffect.transform.modelviewMatrix.)

  2. Call prepareToDraw on the GLKBaseEffect instance. This binds the matrices, textures, and other state you've set in GLKBaseEffect for use by the shaders that class generates for you. (You're doing this before setting each matrix, so the matrices you're setting aren't taking effect when you want.)

  3. After all that, perform an OpenGL draw command (glDrawArrays, glDrawElements, etc.) to draw with the state you've set.

The one additional thing you might think about is whether you've (elsewhere) set a different modelview matrix on your baseEffect and are using it for other draw calls. In that case, you might want to save the current matrix before drawing with a different matrix, then restore it afterward. A matrix stack is useful for that, and GLKit provides one in the GLKMatrixStack type and related functions. But if these are your only draw calls with that effect, or your other calls create a matrix from scratch like these ones do, there's no need to save/restore.

Upvotes: 2

Related Questions