Russian Qt Forum

Qt => OpenGL => Тема начата: Apktyc от Ноябрь 02, 2015, 22:13



Название: [Решено] Проблема с FBO
Отправлено: Apktyc от Ноябрь 02, 2015, 22:13
Здравствуйте.
Попробовал использовать FBO и столкнулся со странным поведением. Корректно работают лишь буферы, созданные до создания первичного буфера.
Допустим, создаю FBO, они получают "номера" 1 и 2. Перед привязкой буфера (glBindFramebuffer(...)/bind()), проверяю текущий - получаю 3 (т.е. это "номер" первичного). Рисую что необходимо, отвязываю через glBindFramebuffer(GL_FRAMEBUFFER, 0) (или release() для QOpenGLFramebufferObject), текущим снова становится 3. Проблем нет.
Снова создаю FBO, они получают "номера" 4 и 5, и вот эти буферы при попытке связывания дают ошибку 1282 (GL_INVALID_OPERATION), и уже ничего нормально не отрисовывается.
Если удалить 1 и 2 буферы и создать вновь, получив те же номера, привязка у них будет также нарушена.

Все буферы создаются корректно, glCheckFramebufferStatus возвращает GL_FRAMEBUFFER_COMPLETE.
Пробовал использовать и класс QOpenGLFramebufferObject, и создавать все нативными командами OpenGL - результат идентичный.
Для отображения используется потомок QOpenGLWidget.

Каковы могут быть причины подобного поведения?

Решение:
Цитировать
It is important that you have a current OpenGL context set when creating the QOpenGLFramebufferObject, otherwise the initialization will fail
Перед созданием FBO предварительно нужно выставить контекст (makeCurrent()). Загвоздка в том, что при не выставленном контексте, QOpenGLFramebufferObject::isValid() все равно возвращает true, что вводило меня в заблуждение, так как я считал буфер валидным.


Название: Re: Проблема с FBO
Отправлено: Igors от Ноябрь 03, 2015, 03:49
...отвязываю через glBindFramebuffer(GL_FRAMEBUFFER, 0)
В букваре пишут
Цитировать
All rendering happens into an OpenGL framebuffer object. makeCurrent() ensure that it is bound in the context. Keep this in mind when creating and binding additional framebuffer objects in the rendering code in paintGL(). Never re-bind the framebuffer with ID 0. Instead, call defaultFramebufferObject() to get the ID that should be bound.
Попробуйте
Код
C++ (Qt)
glBindFramebuffer(GL_FRAMEBUFFER, widget->defaultFramebufferObject());


Название: Re: Проблема с FBO
Отправлено: Apktyc от Ноябрь 03, 2015, 13:15
Igors, спасибо за ответ.
Первый вариант был написан с использованием QOpenGLFramebufferObject, где для отвязки использовался release()/bindDefault() - которые в свою очередь завязаны на defaultFramebufferObject() для текущего контекста - и все равно проблема имела место быть.
Также я проверял, glBindFramebuffer(GL_FRAMEBUFFER, 0) вполне себе восстанавливает правильный первичный буфер, тот что был до привязки моих, но буду осторожней.

В любом случае, ошибка кроется в отказе буферов (созданных после первичного) привязываться (несмотря на то, что метод bind() у QOpenGLFramebufferObject возвращает true), glGetError() после этого возвращает ошибку 1282, и отрисовка происходит в первичный буфер.


Название: Re: Проблема с FBO
Отправлено: Igors от Ноябрь 03, 2015, 13:25
После долгих мытарств я отказался от использования QOpenGLWidget и перешел на QOpenGLWindow - и все как-то сразу рассосалось. Отчаянные попытки разобраться по исходникам что же виджет делает со своим frameBuffer'ом - увы, ни к чему не привели. Его навязчивое кеширование совершенно задолбало  :'(


Название: Re: Проблема с FBO
Отправлено: Apktyc от Ноябрь 03, 2015, 13:43
Да, я помню эту тему http://www.prog.org.ru/topic_28826_0.html (http://www.prog.org.ru/topic_28826_0.html). Ну попробую мигрировать на QOpenGLWindow. Спасибо.