iOS и несколько представлений OpenGL - PullRequest
4 голосов
/ 13 ноября 2011

В настоящее время я разрабатываю приложение для iPad, которое использует OpenGL для рисования некоторых очень простых (не более 1000 или 2000 вершин) вращающихся моделей в нескольких представлениях OpenGL.В настоящее время в сетке 6 видов, каждый из которых имеет собственную ссылку для отображения чертежа.Из-за простоты моделей, это на сегодняшний день самый простой способ сделать это, у меня нет времени на кодирование полного интерфейса OpenGL.

В настоящее время все идет хорошо с точки зрения производительности, но естьнекоторые раздражающие глюки.Первые 3 представления OpenGL отображаются без проблем, а последние 3 отображают только несколько треугольников (сохраняя при этом возможность вращать модель).Также в некоторых случаях вызов glDrawArrays идет прямо в EXC_BAD_ACCESS (особенно на симуляторе), что говорит мне, что с буферами что-то не так.

Что я проверял (такжекак двойной и тройной проверки):

  • Распределение буфера выглядит нормально
  • Все ресурсы освобождены на dealloc
  • Инструменты показывают некоторые предупреждения, но ничего, чтокажется связанным

Я думаю, что это, вероятно, связано с тем, что у меня было несколько видов, рисующих одновременно, так есть ли какая-то известная вещь, которую я должен был там сделать?Каждое представление имеет свой собственный контекст, но, возможно, я что-то не так с этим делаю ...

Кроме того, я только что заметил, что в симуляторе пораженные виды мерцают между правильным рисунком со всеми вершинами инеправильный рисунок с несколькими.

В любом случае, если у вас есть какие-либо идеи, спасибо, что поделились!

Ответы [ 2 ]

9 голосов
/ 15 ноября 2011

Хорошо, я собираюсь ответить на свой вопрос, так как я наконец-то нашел, что происходит.Это была маленькая пропущенная строка, которая вызывала все эти проблемы.

По сути, для одновременного отображения нескольких представлений OpenGL вам необходимо:

  • Любой , одинаковый контекст для каждого представления.Здесь вы должны позаботиться о том, чтобы не рисовать одновременно с несколькими потоками (т.е. как-то заблокировать контекст, как объяснено в этом ответе . И вам необходимо повторно связать буферы кадров и рендерингакаждый раз в каждом кадре.
  • или , вы можете использовать различные контексты для каждого просмотра. Затем вам нужно сбросить контекст каждого кадра , поскольку другие ссылки на отображение могут (и, как в моем случае) приводят к тому, что ваши вызовы OpenGL используют неверные данные. Кроме того, нет необходимости повторно связывать frame- и render-буферы, поскольку ваш контекст сохраняется.

Кроме того, вызывайте glFlush () после каждого кадра, чтобы сообщить графическому процессору о завершении рендеринга каждого кадра полностью.

В моем случае (второй) код для рендеринга каждого кадра (в iOS) выглядит так:

- (void) drawFrame:(CADisplayLink*)displayLink {
  // Set current context, assuming _context
  // is the class ivar for the OpenGL Context
  [EAGLContext setCurrentContext:_context]

  // Clear whatever you want
  glClear (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

  // Do matrix stuff
  ...
  glUniformMatrix4fv (...);

  // Set your viewport
  glViewport (0, 0, self.frame.size.width, self.frame.size.height);

  // Bind object buffers
  glBindBuffer (GL_ARRAY_BUFFER, _vertexBuffer);
  glVertexAttribPointer (_glVertexPositionSlot, 3, ...);

  // Draw elements
  glDrawArrays (GL_TRIANGLES, 0, _currentVertexCount);

  // Discard unneeded depth buffer
  const GLenum discard[] = {GL_DEPTH_ATTACHMENT};
  glDiscardFramebufferEXT (GL_FRAMEBUFFER, 1, discard);

  // Present render buffer
  [_context presentRenderbuffer:GL_RENDERBUFFER];

  // Unbind and flush
  glBindBuffer (GL_ARRAY_BUFFER, 0);
  glFlush();
}

РЕДАКТИРОВАТЬ

Я собираюсь редактироватьэтот ответ, так как я обнаружил, что запуск нескольких CADisplayLinks может вызвать некоторые проблемы.o убедитесь, что для свойства frameInterval вашего экземпляра CADisplayLink установлено значение, отличное от 0 или 1. В противном случае цикл выполнения будет иметь только время для вызова первого метода рендеринга, а затемэто вызовет это снова и снова.В моем случае именно поэтому двигался только один объект.Теперь он установлен на 3 или 4 кадра , и цикл выполнения успевает вызвать все методы рендеринга.

Это относится только к приложению, запущенному на устройстве.Симулятор, будучи очень быстрым, не заботится о таких вещах.

0 голосов
/ 13 ноября 2011

Сложно, когда вам нужны несколько UIViews, которые являются openGLViews,

на этом сайте вы сможете прочитать все об этом: Использование нескольких openGL Views и uikit

...