MKOverlayView и OpenGL

В настоящее время у меня есть UIView, который рисует данные радара поверх MKMapView, используя OpenGL. Из-за уровня детализации радиолокационного изображения требуется OpenGL (CoreGraphics работает недостаточно быстро).

Все изображения, которые я рисую, сохраняются в MKMapPoints. Я предпочитаю их стандартным CLLocationCoordinate2D, потому что их длина не зависит от широты. Базовый метод рисования таков:

  1. Добавьте GLView как подвид MKMapView и установите GLView.frame = MKMapView.frame.
  2. Используя GLOrthof, установите проекцию GLView равной текущей видимой MKMapRect карты. Вот код, который это делает.

    CLLocationCoordinate2D coordinateTopLeft =
        [mapView convertPoint:CGPointMake(0, 0)
                 toCoordinateFromView:mapView];
    MKMapPoint pointTopLeft = MKMapPointForCoordinate(coordinateTopLeft);
    
    CLLocationCoordinate2D coordinateBottomRight =
        [mapView convertPoint:CGPointMake(mapView.frame.size.width,
                                          mapView.frame.size.height)
                 toCoordinateFromView:mapView];
    MKMapPoint pointBottomRight = MKMapPointForCoordinate(coordinateBottomRight);
    
    glLoadIdentity();
    glOrthof(pointTopLeft.x, pointBottomRight.x,
             pointBottomRight.y, pointTopLeft.y, -1, 1);
    
  3. Установите правильный размер области просмотра, используя glViewport(0, 0, backingWidth, backingHeight), где backingWidth и backingHeight - размер mapView в точках.

  4. Нарисуйте, используя glDrawArrays. Не уверен, что это имеет значение, но GL_VERTEX_ARRAY и GL_TEXTURE_COORD_ARRAY включены во время розыгрыша.

При использовании этого метода все работает нормально. Рисунок выполнен так, как и положено. Единственная проблема заключается в том, что поскольку это подвид mapView (а не наложение), изображение радара рисуется поверх любых других MKAnnotations и MKOverlays. Мне нужно, чтобы этот слой был нарисован под другими аннотациями и наложениями.

Что я пытался сделать, чтобы это заработало, так это сделать glView подпредставлением пользовательского MKOverlayView вместо mapView. Что я сделал, так это присвоил MKOverlay boundingMapRect MKMapRectWorld и установил рамку glView так же, как я установил проекцию (поскольку кадр MKOverlayView определяется MKMapPoints, а не CGPoints). Опять же, вот код.

CLLocationCoordinate2D coordinateTopLeft =
    [mapView convertPoint:CGPointMake(0, 0)
             toCoordinateFromView:mapView];
MKMapPoint pointTopLeft = MKMapPointForCoordinate(coordinateTopLeft);

CLLocationCoordinate2D coordinateBottomRight =
    [mapView convertPoint:CGPointMake(mapView.frame.size.width,
                                      mapView.frame.size.height)
             toCoordinateFromView:mapView];
MKMapPoint pointBottomRight = MKMapPointForCoordinate(coordinateBottomRight);

glRadarView.frame = CGRectMake(pointTopLeft.x, pointTopLeft.y,
                               pointBottomRight.x - pointTopLeft.x,
                               pointBottomRight.y - pointTopLeft.y);

Когда я это делаю, glView правильно располагается на экране (в том же месте, что и в то время, когда он был подвидом mapView), но рисунок больше не работает правильно. Когда изображение появляется, оно не того размера и находится в неправильном месте. Я проверил, и backingWidth и backingHeight по-прежнему имеют размер обзора в пунктах (как и должно быть).

Есть идеи, почему это не работает?


person Ross Kimes    schedule 07.01.2012    source источник
comment
Вы уверены, что вам нужно визуализировать радар в реальном времени? Разве предварительная отрисовка (например, один включенный PNG для каждого кадра) не является вариантом?   -  person    schedule 07.01.2012
comment
Короткий ответ, нет. Есть кое-что, что я делаю с данными (и еще кое-что планирую сделать в обновлениях), когда предварительно обработанное изображение не будет работать.   -  person Ross Kimes    schedule 07.01.2012


Ответы (2)


Я слишком долго отсутствовал с iphone, чтобы полностью разобраться в вашем коде, но я, кажется, припоминаю, когда некоторое время назад я испортил Open GL на iPhone, я обнаружил, что необходимо поддерживать свой собственный z-Index и просто рисуйте элементы в таком порядке ... Каждая операция рисования происходила с правильным вращением в 3D, но что-то, нарисованное позже, всегда было поверх того, что было нарисовано ранее. Одна из моих первых тестовых программ рисовала сетку на поверхности, а затем заставляла все это переворачиваться. Я ожидал, что сетка исчезнет, ​​когда обратная сторона объекта будет обращена ко мне, но она оставалась видимой, потому что она была нарисована позже в отдельной операции (IIRC).

Возможно, я делал что-то не так, что вызвало эту проблему, но я решил упорядочить рисунки по z-индексу.

Можете ли вы сначала нарисовать изображение, используя свой первый метод?

person Gus    schedule 31.01.2012
comment
Я не думаю, что это проблема. Я рисую только одно, и это двухмерный рисунок. - person Ross Kimes; 31.01.2012
comment
Так что, возможно, вам нужно нарисовать две вещи ... Может быть, вы могли бы нанести текстуру (с помощью радара) на прямоугольник размером с экран? iphonedevelopment.blogspot.com/2009/ 05 / ... Затем вы можете нарисовать их в нужном вам порядке. - person Gus; 31.01.2012
comment
Вот чем я сейчас занимаюсь, и это работает. Часть, с которой у меня возникли проблемы, - это инкапсуляция этого в MKOverlayView. - person Ross Kimes; 01.02.2012

Я думаю, что вам нужно просто установить область просмотра, прежде чем устанавливать режим проекции.

person c0d3rguy    schedule 01.02.2012
comment
Это тоже не работает. Я пробовал использовать его раньше, непосредственно перед glLoadIdentity () и между glLoadIdentity () и glOrthof (). - person Ross Kimes; 01.02.2012