glPushMatrix()& glPopMatrix()抛出GL_INVALID_OPERATION

时间:2014-09-08 15:21:11

标签: ios objective-c iphone opengl-es opengl-es-2.0

我尝试从传入的iphone麦克风流中绘制波形。提取数据没有问题,绘图工作正常。只有当我使用OpenGL异常断点时,xcode才会在glPushMatrix() & glPopMatrix()处抛出代码为GL_INVALID_OPERATION的异常。我在互联网上搜索了一些更多信息,但我发现的唯一一件事是:

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

我不使用命令glBegin oder glEnd,因为这对我没有帮助。有任何想法吗?这里有什么问题?我画这样的东西:

- (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);
}

初始化就像这样:

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);

2 个答案:

答案 0 :(得分:2)

glPushMatrixglPopMatrix引用固定功能OpenGL管道中的内置矩阵堆栈 - 该功能不在OpenGL ES 2.0中。

然而,你使用它的方式看起来并没有真正做任何事情,你正在做的是错误的顺序。使用GLKBaseEffect绘图需要三个步骤:

  1. 通过GLKBaseEffect实例上的属性设置模型视图和投影矩阵。 GLES 1.x中没有“当前矩阵”或“矩阵模式”隐式状态;只是在GLKBaseEffect上明确命名和单独存储的属性。 (您已经使用设置self.baseEffect.transform.modelviewMatrix的行进行了此操作。)

  2. prepareToDraw个实例上调用GLKBaseEffect。这会绑定您在GLKBaseEffect中设置的矩阵,纹理和其他状态,以供类生成的着色器使用。 (您在设置每个矩阵之前都这样做,因此您设置的矩阵在您需要时不会生效。)

  3. 毕竟,执行OpenGL绘图命令(glDrawArraysglDrawElements等)以使用您设置的状态进行绘制。

  4. 您可能想到的另一件事是您是否(在其他地方)在baseEffect上设置了不同的模型视图矩阵,并将其用于其他绘制调用。在这种情况下,您可能希望在使用不同的矩阵绘制之前保存当前矩阵,然后再将其恢复。矩阵堆栈对此很有用,而GLKit在GLKMatrixStack类型和相关函数中提供了一个。但是,如果这些是您唯一的具有该效果的绘制调用,或者您的其他调用从头开始创建矩阵,就像这些那样,则无需保存/恢复。

答案 1 :(得分:0)

继续我对该主题的研究,答案似乎是OpenGL ES 2.0确实不支持矩阵堆栈或推/弹,请参阅here.