ios - glPushMatrix() 和 glPopMatrix() 抛出 GL_INVALID_OPERATION

标签 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 或 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);

最佳答案

glPushMatrixglPopMatrix 指的是来自固定功能 OpenGL 管道的内置矩阵堆栈——该功能不在 OpenGL ES 2.0 中。

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

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

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

  3. 之后,执行 OpenGL 绘图命令(glDrawArraysglDrawElements 等)以您设置的状态进行绘图。

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

关于ios - glPushMatrix() 和 glPopMatrix() 抛出 GL_INVALID_OPERATION,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25727634/

相关文章:

javascript - Mobile safari 崩溃日志 - 内存不足

objective-c - 需要关于哪个选项可以有效地在 iPad 上存储数据的建议

ios - -distanceFromLocation : 中 CLLocation 对象的顺序

ios - 防止在 iOS7 tableview 编辑模式下向左拖动单元格

objective-c - 如何使 FMDB 的数据库成为单例

iphone - CMSampleBufferRef 内存泄漏

ios - TextField 和 Button 没有出现在容器 View 中?

ios - iOS 中水印图像大小根据视频大小而变化

objective-c - 让动画等待 1 秒 – Objective-c

ios - 如何将 cocoapods 添加到现有项目?