OpenGL,glDrawArrays和IOS,Bad Access?

时间:2012-02-12 12:26:38

标签: objective-c ios xcode opengl-es

我开始在iOS中使用OpenGL。我总是学习使用glBegin()glEnd()在OpenGL中绘制内容,所以这对我来说是个新鲜事。

我想画一个简单的三角形。我可以很好地绘制一个白色三角形,甚至可以使用glColor绘制整个彩色三角形。但每当我尝试使用下面的代码为每个顶点指定颜色时,绘制数组时会得到EXC_BAD_ACCESS。我正在使用iOS 4.3模拟器。我做错了什么?

- (void) render:(CADisplayLink*)displayLink {
    glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    GLfloat vertices [] = {0,0,0, 0,100,0, 100,0,0};
    GLfloat colours [] = {1.0,1.0,1.0, 1.0,1.0,1.0, 1.0,1.0,1.0};
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, vertices);
    glColorPointer(3, GL_FLOAT, 0, colours);
    glDrawArrays(GL_TRIANGLES, 0, 3);   <-- CRASHES HERE
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);

    [self.context presentRenderbuffer:GL_RENDERBUFFER];
}    

2 个答案:

答案 0 :(得分:5)

glColorPointer(3, GL_FLOAT, 0, colours)生成GL_INVALID_VALUE错误(您可以看到在执行该行后立即执行po glGetError,它将打印1281)。

原因是OpenGL ES不支持3种颜色组件,documentation状态:

  如果size不是4,则生成

GL_INVALID_VALUE

如果通过添加alpha将颜色分量的数量更改为4,则代码​​将无效。

答案 1 :(得分:1)

到目前为止,您的OpenGL代码看起来是正确的。 对glDrawArrays的调用会导致访问权限不佳,还是在其中发生错误访问? 我可以想象,glDrawArrays func指针未初始化, 顶点数组应该可用。

你可以在glEnableClientState(GL_COLOR_ARRAY);之后调用此函数 作为重置任何其他陈旧数组指针的测试,这可能导致错误访问:

///@brief Emulation of call glClientAttribDefaultEXT(GL_CLIENT_VERTEX_ARRAY_BIT) according to GL_EXT_direct_state_access.

static void ClientAttribDefaultVertexArray(void) {
    int i;
    GLint max;

    glBindBufferARB(GL_ARRAY_BUFFER, 0);
    glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);

    glDisableClientState(GL_EDGE_FLAG_ARRAY);
    glEdgeFlagPointer(0, 0);

    glDisableClientState(GL_INDEX_ARRAY);
    glIndexPointer(GL_FLOAT, 0, 0);

    glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
    glSecondaryColorPointer(4, GL_FLOAT, 0, 0);

    glDisableClientState(GL_FOG_COORD_ARRAY);
    glFogCoordPointer(GL_FLOAT, 0, 0);

    glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max);
    for (i = 0; i < max; ++i) {
        glClientActiveTextureARB(GL_TEXTURE0 + i);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
        glTexCoordPointer(4, GL_FLOAT, 0, 0);
    }

    glDisableClientState(GL_COLOR_ARRAY);
    glColorPointer(4, GL_FLOAT, 0, 0);

    glDisableClientState(GL_NORMAL_ARRAY);
    glNormalPointer(GL_FLOAT, 0, 0);

    glDisableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(4, GL_FLOAT, 0, 0);

    glDisableClientState(GL_WEIGHT_ARRAY_ARB);
    glWeightPointerARB(0, GL_FLOAT, 0, 0);

    glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &max);
    for (i = 0; i < max; ++i) {
        glDisableVertexAttribArrayARB(i);
        glVertexAttribPointerARB(i, 4, GL_FLOAT, GL_FALSE, 0, 0);
    }

    glClientActiveTextureARB(GL_TEXTURE0);
}

此外,您可以在客户端attrib堆栈上推送和弹出顶点数组状态:

glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);

///vertex array init and usage

glPopClientAttrib();