glDrawArrays 上的 OpenGL ES EXC_BAD_ACCESS

发布于 2024-11-10 01:55:48 字数 4704 浏览 4 评论 0原文

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

以下是我的其他渲染代码。它在运行循环中的上述代码之前被调用。下面的一切似乎都工作正常。

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

相关缓冲区已在其他地方设置,并且如上所述,第二个代码一切正常。

基本上,我在顶部代码片段中的drawArrays代码上得到了EXC_BAD_ACCESS。有人知道为什么吗?

谢谢

I'm having an issue rendering in OpenGL ES 1.1 for an iPhone game that I'm building.

In short, I am rendering 3 items:

  1. Background (works fine)
  2. A number of spherical objects (works fine)
  3. A simple line circle that changes size (I am getting a problem here).

Basically, I am getting an EXC_BAD_ACCESS error when I call drawArrays on the circle. I have tested the code in the basic iPhone OpenGL template and it works just fine, so I can't really track why it's not working here. Can someone point me in the right way?

Here is the drawCircle code used to render the circle.

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

And the following is my other rendering code. It is called prior to the above code in the run loop. Everything in the following seems to work OK.

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

The relevant buffers have been set-up elsewhere, and as mentioned, the second code all works fine.

Basically, I am getting an EXC_BAD_ACCESS on the drawArrays code in the top code snippet. Anyone have any ideas why?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

缪败 2024-11-17 01:55:48

我的猜测是 GL 状态有一个不应该绑定的数组仍然被绑定。

如果它本身有效,那么该方法可能没问题。但是以前的方法可能没有将状态返回到应有的状态或其他状态。

My guess is the GL state has an array still bound that shouldn't be.

If it works on its own, then that method might be fine. But a previous method may not have returned the state to what it should be or something.

走走停停 2024-11-17 01:55:48

当尝试从图形库或引擎(例如 Cocos2D)内进行低级 OpenGL 调用时,也会发生这种崩溃。例如,Cocos2D 设置了一些启用的 GL 状态:GL_TEXTURE_COORD_ARRAY、GL_VERTEX_ARRAY、GL_COLOR_ARRAY。
在此示例中,如果您的代码不使用纹理,它将崩溃,除非您禁用 GL_TEXTURE_COORD_ARRAY。

感谢 v01d 的暗示!

This kind of crash also happen when trying to make low-level OpenGL calls from within graphics libraries or engines, e.g. Cocos2D. For example, Cocos2D sets handful of GL states enabled: GL_TEXTURE_COORD_ARRAY, GL_VERTEX_ARRAY, GL_COLOR_ARRAY.
In this example, if yor code do not make use of texturing, it will crash unless you disable GL_TEXTURE_COORD_ARRAY.

Thanks v01d for hinting that!

策马西风 2024-11-17 01:55:48

正如 v01d 所说,您忘记解除绑定先前状态的缓冲区,请使用以下代码清除它。

glBindBuffer(GL_ARRAY_BUFFER, 0)

As v01d said, you forget to unbind the buffer of previous state, use followed code to clear it.

glBindBuffer(GL_ARRAY_BUFFER, 0)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文