9
votes

OpenGL es exc_bad_access sur GLDRAWARRAIS

J'ai un problème de rendu dans OpenGL ES 1.1 pour un jeu iPhone que je bâche.

En bref, je rendu 3 articles: p>

  1. fond (fonctionne bien) li>
  2. Un certain nombre d'objets sphériques (fonctionne bien) li>
  3. Un cercle de ligne simple qui change de taille (je pose problème ici). Li> ol>

    Fondamentalement, je reçois une erreur exc_bad_access lorsque j'appelle des arrières sur le cercle. J'ai testé le code dans le modèle de base iPhone OpenGL et ça fonctionne très bien, donc je ne peux donc pas vraiment suivre pourquoi cela ne fonctionne pas ici. Quelqu'un peut-il me signaler de la bonne façon? P>

    Voici le code de dessinateur utilisé pour rendre le cercle. P> xxx pré>

    et ce qui suit est mon autre code de rendu . Il est appelé avant le code ci-dessus dans la boucle d'exécution. Tout dans ce qui suit semble fonctionner correctement. P>

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


2 commentaires

Rendez-vous cela sur un fil de fond? Y a-t-il une chance que quelque chose d'autre puisse accéder au contexte OpenGL en même temps que cela? J'ai vu cela causée comme celle-ci dans le passé.


Non, c'est sur le fil principal, et je n'ai rien d'autre qui fonctionne sur un fil de fond qui pourrait accéder au contexte. Au fait, j'ai apprécié vos conférences sur OpenGL: ils étaient très utiles quand je précise d'apprendre quelques mois de retour! [Puis-je vous tenir à blâmer si je ne peux pas résoudre ce problème OpenGL? :-)]


3 Réponses :


10
votes

Je suppose que l'état GL a une matrice toujours liée qui ne devrait pas être.

Si cela fonctionne seul, cette méthode pourrait aller bien. Mais une méthode précédente n'aurait peut-être pas renvoyé l'État à ce que cela devrait être ou quelque chose.


5 commentaires

Merci v01d, je pense que vous pourriez être sur les bonnes lignes. J'ai quelques autres fonctions utilisées pour initialiser la configuration opengl, les textures, etc. Je vais essayer de travailler à nouveau, et si je ne peux pas résoudre le problème, je posterai le code restant.


Une chose que vous voudrez peut-être essayer aussi, c'est une méthode / macro facile à vérifier l'état GL Error et Abort si on se trouve. Et puis allez-y fou le poivré autour de votre code. Si vous avez le débogueur en cours d'exécution, vous attrapez une erreur tôt. Ce n'est pas que c'est ce qui est nécessairement votre problème, mais j'ai eu un mauvais accès des accidents d'accès plus tard à partir d'un appel précédent qui a été mal formé. Si vous en faites un appel de macro, vous pouvez le rendre facilement désactivé pour la libération, puis vous pouvez laisser les vérifications d'erreur dans votre code.


Merci v01d, cela semble un très bon plan. Je vais essayer cela un peu plus tard et voir si je peux trouver quelque chose.


Ok, alors j'ai finalement suivi le problème et v01d avait raison. Dans le code ci-dessus, je n'avais pas franchi les tampons d'élément et de matrice que j'utilisais pour rendre les objets «digues» à l'écran. Quand je les inconscile en ajoutant "GLBindbuffer (GL_ARray_Buffer, 0)" et "GLBindbuffer (GL_ELEMENT_ARRAY_BUPER, 0)" À la fin de ma fonction de rendu, j'ai pu rendre un objet séparé à l'aide de Gldrawarrays plus tard.


La suggestion de Glerror m'a aidé - j'avais le même crash, mais j'écoulais dans mon cas gl_unsigned_short à Glvertexpoinger et pas gl_short :) soupir.



2
votes

Ce type de crash se produit également lorsque vous essayez de faire des appels opengl à bas niveau à partir de bibliothèques ou de moteurs graphiques, par ex. Cocos2d. Par exemple, Cocos2D définit la poignée d'états GL activés: GL_Texture_COord_array, GL_VERTEX_ARRAY, GL_COLOR_ARRAY. Dans cet exemple, si le code de Yor ne recueille pas de texturation, il se bloque que si vous désactivez GL_TEXTURE_COORD_ARRAY.

merci v01d pour avoir affiché ça!


0 commentaires

0
votes

comme V01D dit, vous oubliez d'engager le tampon de l'état précédent, utilisez le code suivi pour l'effacer.

glBindBuffer(GL_ARRAY_BUFFER, 0)


0 commentaires