Должен любить эти ласка слова ... "Мы испортим фоновую загрузку навсегда (геометрия может быть огромной), чтобы нам не пришлось реализовывать новый / лучший код в наших драйверах";).
ер: Я уверен, что ответNO
, но это только после дня очень расстроенной отладки. Теперь я хотел бы знать, так ли это на самом деле (и если да, то как я мог знать), или я просто делаю что-то совершенно неправильно.
Вот ситуация. Я использую OpenGL ES 2.0 для рендеринга некоторых мешей, загружаемых из разных файлов (.obj, .md2 и т. Д.). Ради производительности и пользовательского опыта я делегирую фактическую загрузку этих мешей и связанных с ними текстур фоновому потоку с помощью GCD.
вApple, инструкциив каждом фоновом потоке я создаю и устанавливаю новый EAGLContext с тем жеshareGroup
в качестве основного контекста рендеринга. Это позволяет объектам OpenGL, таким как объекты текстуры и буфера, которые были созданы в фоновом потоке, немедленно использоваться контекстом в основном потоке.
Это прекрасно работает. Теперь я недавно узнал оVertex Array Objects как способ кэширования состояния OpenGL, связанного с рендерингом содержимого определенных буферов. Это выглядит красиво, и сокращает проверку состояния шаблона и код установки, необходимый для рендеринга каждой сетки. Кроме того, Apple также рекомендует использовать их в своихЛучшие практики для работы с данными вершин руководство.
Но у меня были серьезные проблемы с тем, чтобы заставить ВАО работать на меня вообще. Как и при любой загрузке, я бы загружал сетку из файла в память в фоновом потоке, а затем генерировал все связанные объекты OpenGL. В обязательном порядке я первый раз попробовал позвонитьglDrawElements()
используя VAO, приложение вылетает сEXC_BAD_ACCESS
, Без ВАО, это делает хорошо.
отладкаEXC_BAD_ACCESS
Это боль, особенно когда NSZombies не поможет (что, очевидно, не поможет), но после некоторого времени анализа захваченных кадров OpenGL я понял, что, хотя создание VAO в фоновом потоке прошло нормально (нетGL_ERROR
и ненулевой идентификатор), когда пришло время связываться с VAO в главном потоке, я бы получилGL_INVALID_OPERATION
, которыйдокументы состояние будет происходить при попытке привязки к несуществующей VAO. И, конечно же, при просмотре всех объектов в текущем контексте во время рендеринга не видно ни одного VAO,но все VBO, которые были созданы с VAOВ ТО ЖЕ ВРЕМЯ присутствуют, Если я загружаю VAO в основной поток, он работает нормально. Очень расстраивает.
Я перевел код загрузки в более атомарную форму:
- (void)generate {
glGenVertexArraysOES(1, &_vao);
glBindVertexArrayOES(_vao);
_vbos = malloc(sizeof(GLuint) * 4);
glGenBuffers(4, vbos);
}
Когда вышеуказанное выполняется в фоновом потоке, с действительнымEAGLContext
с тем жеshareGroup
в качестве основного контекста основной контекст будет иметь 4 VBO, но не VAO. Если я выполню его в главном потоке с основным контекстом, у него будет 4 VBO и VAO. Это приводит меня к выводу, что есть некое странное исключение из природы совместного использования объектов.EAGLContext
при работе с ВАО. Если бы это было на самом деле, я бы действительно ожидал, что документы Apple заметят это где-то. Это очень неудобно, чтобы открывать маленькие лакомые кусочки вручную. Это тот случай, или я что-то упустил?