Невозможно вызвать 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.