glDrawArrays上的OpenGL ES EXC_BAD_ACCESS

pay*_*nio 9 iphone render exc-bad-access opengl-es

我正在使用OpenGL ES 1.1渲染我正在构建的iPhone游戏.

简而言之,我渲染了3个项目:

  1. 背景(工作正常)
  2. 一些球形物体(工作正常)
  3. 一个改变大小的简单线圈(我在这里遇到问题).

基本上,当我在圆圈上调用drawArrays时,我收到一个EXC_BAD_ACCESS错误.我已经测试了基本的iPhone OpenGL模板中的代码,它工作正常,所以我无法真正跟踪它为什么不在这里工作.有人能以正确的方式指出我吗?

这是用于渲染圆的drawCircle代码.

- (void) drawCircles
{
if (!m_circleEffects.empty())
{
    int segments = 24;
    for (int i = 0; i < m_circleEffects.size(); i++)
    {
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glTranslatef(m_circleEffects[i].position.x, m_circleEffects[i].position.y, 0);

        float radius;
        if(m_circleEffects[i].isPulseOutward)
            radius = cos(m_circleEffects[i].frameCounter * M_PI / 720);
        else
            radius = sin(m_circleEffects[i].frameCounter * M_PI / 720);

        GLfloat circlePoints[segments * 3];                    
        int count = 0;

        for (GLfloat i = 0; i < 360.0f; i += (360.0f / segments))
        {
            circlePoints[count++] = (cos(i * M_PI / 180) * radius);
            circlePoints[count++] = (sin(i * M_PI / 180) * radius);
            circlePoints[count++] = z + 1;
        }

        glEnableClientState(GL_VERTEX_ARRAY);  
        glVertexPointer(3, GL_FLOAT, 0, circlePoints);                       
        glDrawArrays(GL_LINE_LOOP, 0, segments);   
        glDisableClientState(GL_VERTEX_ARRAY);
    }      
    m_circleEffects.clear();
}
}
Run Code Online (Sandbox Code Playgroud)

以下是我的其他渲染代码.它在运行循环中的上述代码之前调用.以下所有内容似乎都可以正常工作.

- (void)passInVisualsToUse:(vector<Visual>)visuals
{
frameCounter += 0.2;
if (frameCounter >= 360)
    frameCounter -= 360;

glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);

glDepthMask(GL_FALSE);

glBindTexture(GL_TEXTURE_2D, m_backgroundTexture);

glDrawTexfOES(0, 0, 0, 480, 320);
glDepthMask(GL_TRUE);

vector<Visual>::const_iterator visual = visuals.begin();
for (int visualIndex = 0;
     visual != visuals.end();
     ++visual, ++visualIndex)
{        

    if (visual->ObjectType == 1)
        glBindTexture(GL_TEXTURE_2D, m_oneTexture);
    else if (visual->ObjectType == 2)
        glBindTexture(GL_TEXTURE_2D, m_twoTexture);
    else if (visual->ObjectType == 3)
        glBindTexture(GL_TEXTURE_2D, m_threeTexture);
    else
        glBindTexture(GL_TEXTURE_2D, m_fourTexture);

    // Set the viewport transform.
    vec3 position = visual->Position;

    // Set the light position.
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glTranslatef(position.x, position.y, position.z);
    float rotationAngle = visual->RotationAngle;
    glRotatef(rotationAngle, 0, 1, 0);

    float scale = visual->Scale;   

    if (visual->ShouldThrob)
    {
        float scaleFactor = scale + sin(frameCounter) / 25;
        glScalef(scaleFactor, scaleFactor, scale);

        BOOL isPulseOutward;
        if (visual->isPulseOutward)
            isPulseOutward = YES;
        else
            isPulseOutward = NO;

        CircleEffect toAdd;
        toAdd.position = position;
        toAdd.frameCounter = frameCounter;
        toAdd.isPulseOutward = isPulseOutward;
        m_circleEffects.push_back(toAdd);
    }
    else
        glScalef(scale, scale, scale);

    // Set the projection transform.
    float h = (float)screenSize.size.height / (float)screenSize.size.width;

    mat4 projection = mat4::Ortho(xleft, xright, h * xleft, h * xright, znear, zfar);

    glMatrixMode(GL_PROJECTION);
    glLoadMatrixf(projection.Pointer());

    // Draw the surface.
    int stride = sizeof(vec3) + sizeof(vec3) + sizeof(vec2);
    const GLvoid* texCoordOffset = (const GLvoid*) (2 * sizeof(vec3));
    const Drawable& drawable = m_drawables[visualIndex];
    glBindBuffer(GL_ARRAY_BUFFER, drawable.VertexBuffer);
    glVertexPointer(3, GL_FLOAT, stride, 0);
    const GLvoid* normalOffset = (const GLvoid*) sizeof(vec3);
    glNormalPointer(GL_FLOAT, stride, normalOffset);
    glTexCoordPointer(2, GL_FLOAT, stride, texCoordOffset);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, drawable.IndexBuffer);
    glDrawElements(GL_TRIANGLES, drawable.IndexCount, GL_UNSIGNED_SHORT, 0);
}


glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
}
Run Code Online (Sandbox Code Playgroud)

已经在其他地方设置了相关缓冲区,如上所述,第二个代码都可以正常工作.

基本上,我在顶部代码片段中的drawArrays代码上获得了EXC_BAD_ACCESS.有人有什么想法吗?

谢谢

v01*_*01d 10

我的猜测是GL状态有一个不应该绑定的数组.

如果它自己工作,那么该方法可能没问题.但是之前的方法可能没有将状态返回到它应该是什么或什么.

  • 好的,所以我终于找到了问题,v01d是对的.在上面的代码中,我没有解除我用于在屏幕上渲染"可绘制"对象的元素和数组缓冲区.当我通过在渲染函数的末尾添加"glBindBuffer(GL_ARRAY_BUFFER,0)"和"glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0)"来解绑它们时,我之后能够使用glDrawArrays渲染一个单独的对象. (3认同)
  • 您可能还想尝试的一件事是,使用一个简单的方法/宏来检查GL错误状态,如果找到一个则中止.然后疯狂地在你的代码周围加油.如果你运行调试器,你会很早就收到错误.并不是说这就是你的问题,但是我之前的一次电话会出现错误的访问崩溃.如果您将其设置为宏调用,则可以使其轻松禁用以进行发布,然后您可以在代码中保留错误检查. (2认同)