Невозможно вызвать glGenTextures в многопоточном приложении для Android

2 lyomi [2010-08-20 05:57:00]

Я делаю Android-приложение OpenGLES с помощью Android NDK, расширяя его по сравнению с примером android gljni, который можно найти здесь

Используется GLSurfaceView. Текстуры инициализируются в функции JNI, вызванной onSurfaceChanged() из GLSurfaceView.Renderer

Когда пользователь прикасается к экрану, для приложения требуется больше текстур. Для этого glGenTextures() вызывается в функции JNI, вызываемой в onTouchEvent().

Проблема в том, что идентификатор потока (возвращаемый gettid()) кажется полностью произвольным и не всегда одинаковым с идентификатором потока, который имеет контекст OpenGL.

Он загружает и показывает текстуры, если функция JNI вызывается в том же потоке, но не работает, если она находится в другом потоке. Таким образом, он действует довольно случайным образом.

Могу ли я сделать что-то вроде:

  • поделиться контекстом OpenGL, чтобы я мог успешно вызвать glGenTextures() в любом потоке.

  • сделать onTouchEvent() для вызова только в одном потоке, который имеет контекст OpenGl

  • или что-нибудь, что я могу заставить его работать

?

Спасибо

android android-ndk opengl-es textures


4 ответа


2 Решение Matias Valdenegro [2010-08-20 07:32:00]

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


2 lyomi [2010-08-20 06:13:00]

Я работал с GLSurfaceView.queueEvent().

В документе говорится, что GLSurfaceView бережно относится к разделению нити потока и потока рендеринга, а

queueEvent() запускает код в потоке рендеринга.


2 Moncader [2010-08-20 06:09:00]

Я не работал с NDK и OpenGL. Но с чистой версией Java вы не можете делиться потоками. GLSurfaceView не любит разделять контексты GL между потоками. Причиной этого (из того, что я мог сказать) является то, что после вызова drawFrame() контекст теряется. Если вы попытаетесь использовать этот контекст, а не внутри onSurfaceCreated, onSurfaceChanged или onDrawFrame(), ваши методы GL не будут работать. Поэтому с другим потоком существует высокая вероятность того, что, когда этот другой поток выполнит, поток GL уже завершил свой метод drawFrame(), недействительный контекст.


0 Rodja [2013-11-02 13:27:00]

Я описал java-единственное решение для загрузки текстур в отдельном потоке в качестве ответа на другой вопрос: Процесс загрузки текстур Threading для игры android opengl

Он должен работать довольно схожим с NDK.