#opengl-es #android-ndk
#opengl-es #android-ndk
Вопрос:
Когда я поворачиваю свое устройство и получаю результаты моего приложения APP_CMD_CONFIG_CHANGED
, я пытаюсь обновить окно просмотра OpenGL следующим образом:
EGLint width;
EGLint height;
eglQuerySurface(display,surface,EGL_WIDTH,amp;width);
eglQuerySurface(display,surface,EGL_HEIGHT,amp;height);
glViewport(0,0,width,height);
MY_LOG_MACRO2("New window size: %d x %d",width,height);
Это работает примерно в 20% случаев. Остальные 80% времени ширина и высота являются предыдущими значениями. Другими словами, большую часть времени, когда я перевожу свое устройство в альбомный режим, записывается портретный размер. И когда я возвращаюсь к портрету, записывается размер ландшафта.
Мне не очень повезло с получением размера из ANativeWindow
либо.
Что я должен делать, чтобы получить правильный размер окна после поворота?
Обновить:
Ожидая несколько кадров после APP_CMD_CONFIG_CHANGED
, размер всегда правильный. Запрос размера каждого кадра без учета APP_CMD_CONFIG_CHANGED
и проверка, изменился ли он, похоже, также работает, но кажется неправильным.
Комментарии:
1. Где вы вызываете этот код? Контекст Opengl зависит от потока. Если этот код выполняется в случайном потоке, он может работать только при использовании потока с заданным контекстом
2. @crazyjul В моем приложении есть только один поток. Эта функция вызывается, когда ALooper_pollAll получает
APP_CMD_CONFIG_CHANGED
событие, а затем я запускаюpollSource->process(appState,pollSource)
. Мой цикл событий почти идентичен образцу кода.3. Сообщение с форумов Android с той же проблемой groups.google.com/group/android-ndk/browse_thread/thread /…
Ответ №1:
Для обнаружения изменения ориентации экрана я решил не перехватывать APP_CMD_CONFIG_CHANGED
, а вызывать eglQuerySurface()
каждый кадр. Если значения размера экрана не соответствуют сохраненным значениям, ориентация экрана была изменена.
Два вызова eglQuerySurface()
для получения ширины и высоты занимают около 10 микросекунд (100 миллисекунд при вызове 10000 раз), поэтому это не снижает производительность и дает 100% гарантию того, что поворот экрана будет обработан.
Я думаю, что это решение лучше, чем ждать несколько кадров после APP_CMD_CONFIG_CHANGED
. Кстати, поворот устройства на 180 градусов (вверх ногами) вызывает получение APP_CMD_CONFIG_CHANGED
события, но на самом деле ориентация экрана не была изменена, и никаких действий, зависящих от изменения размера, выполняться не должно.
Ответ №2:
Это может не сработать, потому что, например, размер поверхности может быть установлен при создании контекста, и вы запрашиваете «предыдущий» размер (при создании контекста). Редактировать: я протестировал его на SGS2 (2.3.5), и я сразу получаю правильные результаты, так что это может быть проблема с поставщиком устройства (или проблема с версией Android).
Редактирование 2: похоже, я допустил какую-то ошибку во время тестирования, я тоже получаю странные результаты как @IronMensan. Иногда это работает правильно, но в основном нет. Извините за мою ошибку. Поэтому я бы остался при воссоздании контекста EGL, как в моем первоначальном ответе (ниже).
Когда я получаю APP_CMD_CONFIG_CHANGED, я просто просто уничтожаю и воссоздаю контекст EGL (с шейдерами, текстурами и т. Д.), аналогично, Когда я получаю APP_CMD_TERM_WINDOW -> APP_CMD_INIT_WINDOW.
Комментарии:
1. Взгляните еще раз на вопрос и обновление, которое я только что добавил — размер поверхности изменяется, просто обычно не сразу. В среднем требуется около пяти кадров.
2. @IronMensan: я только что протестировал его, и он работает правильно, после того, как я получу APP_CMD_CONFIG_CHANGED, тогда eglQuerySurface(EGL_WIDTH / EGL_HEIGHT) немедленно выдает мне правильные результаты. Протестировано на SGSII (2.3.5-KI3). Так что это может быть проблема с реализацией какого-то поставщика. Какое у вас устройство и версия Android?
3. HTC Evo 4G Android 2.3.3. Похоже, тестирование совместимости будет более болезненным, чем я ожидал.
4. Для справки, у меня есть герой, работающий под управлением Gingerbread 2.3.4 (через модифицированный ROM, я использую Elelinux), и я тоже это вижу.
5. @IronMensan: я отредактировал свой ответ, я вижу такое же странное поведение.