0

アプリについて: ベース マップの上にオーバーレイを描画する機能を備えたタイルで構築されたカスタム openGL マップ。このアプリは、iPad と iPhone の両方に対応しています。一部のオーバーレイはタイル ベースで、まったく問題なく動作しています。いくつかは、マップ上の特定の座標に描かれた円でできています。円をクリックすると、マップ上のこの特定のポイントに関する情報を含むポップオーバー ビューが開きます。iPhone ライブラリでは、WEPopover は UIPopoverViewController と同様の機能を実装するために使用されます。

この問題は iPhone とデバイスでのみ発生します。オーバーレイが大量の円で構成されている場合、情報を含むポップオーバー ビューを開くと、オーバーレイが点滅し、最終的に次の行で EXC_BAD_ACCESS がクラッシュすることがあります: glDrawArrays(GL_LINE_LOOP, 0, 360); これは iPhone でのみ発生し、iPad やシミュレーターでは発生しません。

ちょっとしたコード:

白い輪郭で黒い円を描く:

  for (int i = [pointsArray count]-1; i >= 0; i--) {
       int pinColor = 0xffff0000;

       static GLfloat vertices[720];

         for (int i = 0; i < 720; i += 2) {
         vertices[i]   = (cos(DEGREES_TO_RADIANS(i)) * scale * 1.5);
         vertices[i+1] = (sin(DEGREES_TO_RADIANS(i)) * scale * 1.5);
         }

        glVertexPointer(2, GL_FLOAT, 0, vertices);

        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        glEnable(GL_BLEND);
        glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        for (int dx = x0; dx <= x1; dx++)
        {
            glPushMatrix();

            GLubyte a = (pinColor >> 24) & 0xff;
            a = MIN((GLubyte) (opacity * 255), a);
            glColor4ub(0, 0, 0, a);

            GLfloat xx = point.x - centerX + dx * mapWidth;
            xx *= zoom;
            glTranslatef(xx, yy, 0);

            glDrawArrays(GL_TRIANGLE_FAN, 0, 360); <-----sometimes crash here

            int color = 0xffffffff;

            GLubyte n = (color >> 24) & 0xff;
            GLubyte r = (color >> 16) & 0xff;
            GLubyte g = (color >> 8) & 0xff;
            GLubyte b = (color >> 0) & 0xff;
            n = MIN((GLubyte) (opacity * 255), n);
            glColor4ub(r,g,b,n);

            glLineWidth(1);
            glDrawArrays(GL_LINE_LOOP, 0, 360); <------crash here
            glLineWidth(1);


            glPopMatrix();

        }

        glDisable(GL_BLEND);
        glDisableClientState(GL_VERTEX_ARRAY);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);

        glVertexPointer(2, GL_FLOAT, 0, 0);
  }

iPhoneでポップオーバーを開く:

    WEPopoverController *_popover = [[WEPopoverController alloc] initWithContentViewController:pointDetails];
            _popover.popoverContentSize = pointDetails.view.frame.size;

            if ([[UIDevice currentDevice] orientation] == UIDeviceOrientationLandscapeLeft || [[UIDevice currentDevice] orientation] ==  UIDeviceOrientationLandscapeRight) 
            {

                CGRect myrect2 = CGRectMake(xx,yy, 1, 1);
                [_popover presentPopoverFromRect:myrect2 inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

            } else {

                CGRect myrect2 = CGRectMake(xx, yy, 1, 1);
                [_popover presentPopoverFromRect:myrect2 inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
            }
            self.detailsPopIphone = _popover;
            [_popover release];    

画面に触れるたびに (マップのスケールを移動し、ポップオーバーを開く)、openGL マップが再レンダリングされます。

追加情報やコードがあれば喜んで提供いたします。

4

1 に答える 1

0

この問題を修正しました。問題は、openGL オーバーレイのレンダリングと WEPopover のアニメーションが同時に発生し、競合が発生していたことです。レンダリングとアニメーションが次々に発生するようにコードを整理すると、問題が解決しました。

于 2012-04-22T18:33:38.930 に答える