Russian Qt Forum

Qt => OpenGL => Тема начата: Igors от Октябрь 05, 2016, 07:16



Название: Отлов бага [рещено]
Отправлено: Igors от Октябрь 05, 2016, 07:16
Добрый день

Рисую шейдерами в QOpenGLWindow, все норм, что хотел то и отрисовал. Потом поверх нарисованного надо добавить кое-какую инфу, напр номер кадра (первый маленький аттач). Это делаю через QPainter. И вот иногда получаю какую-то бяку вместо пр-ка (второй "высокий" аттач). Удалось быстро найти в каком случае это происходит, причем 100% стабильно, т.е, всегда. Казалось бы - дело в шляпе, в том коде и искать. Ищу, по существу дело сводится
Код
C++ (Qt)
if (!haColors)
shader->disableAttributeArray(loc);    //  так бага нет
else {
shader->enableAttributeArray(loc);
glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, true, 0, data);  // так есть
}
 
Т.е. единственное что делает этот код - посылает данные шейдеру. Разумеется десяток раз пере-проверил что размер данных корректен, хотя мог и не проверять - объект для которого посылаются эти данные рисуется полностью.

Ладно, полазил в QPainter как он делает fillRect, Следы ведут в OpenGL машину рисования которая заряжает свой шейдер (может создавая его динамически) и в конце-концов вызывает родной glDrawElements

В общем, оказался "у разбитого корыта" - есть причина, есть следствие, и.. и.. ничего :) Ну и что делать? (песни типа "баг в др месте, здесь он просто проявляется" я и сам умею петь)

Спасибо


Название: Re: Отлов бага
Отправлено: ssoft от Октябрь 05, 2016, 08:35
Наверное не стоит смешивать отображение через QPainter и собственную реализацию. Прежде чем рисовать с помощью QPainter необходимо деинициализировать (unbind'ить) собственные настройки, как в прочем и свою реализацию писать сугубо в рамках

Код:
painter->beginNativePainting();
...
painter->endNativePainting();

По крайней мере у меня никогда подобных проблем не возникало, хотя подобный способ отображения не раз использовал.

То есть

- порисовали паинтером
- порисовали самостоятельно
...

но никогда одновременно совместно.


Название: Re: Отлов бага
Отправлено: __Heaven__ от Октябрь 05, 2016, 09:16
Есть такая проблема. Так понимаю, что painter ожидает дефолтный контекст. Получается, что необходимо вернуть всё в состояние как было перед рисованием пэинтером.


Название: Re: Отлов бага
Отправлено: Igors от Октябрь 05, 2016, 09:37
Наверное не стоит смешивать отображение через QPainter и собственную реализацию.
Конечно можно рисовать пр-ки без QPainter - но неудобно, а текст вообще трудно. Ведь есть же пример overPainting, рисование пайнтером "поверх" вполне легально (по крайней мере в теории). К тому же мне "смешивать" мне и не надо, просто "поверх"

..как в прочем и свою реализацию писать сугубо в рамках
Код:
painter->beginNativePainting();
...
painter->endNativePainting();
Конечно пробовал, все то же

Есть такая проблема. Так понимаю, что painter ожидает дефолтный контекст. Получается, что необходимо вернуть всё в состояние как было перед рисованием пэинтером.
Ну как "все" - у меня есть скомпилированные шейдера, есть буфера VBO и.т.п., я их отбиндил (кстати необязательно, QPainter и сам это делает), но убивать их я не могу.

Сейчас получается так: если в моем шейдере объявлено 2 вертексных атрибута - все норм, если 3 и больше - баг. Пробовал их дизаблить (перед QPainter) - тогда вообще летит.


Название: Re: Отлов бага
Отправлено: ssoft от Октябрь 05, 2016, 10:03
Рисую таким образом

Код
C++ (Qt)
void GraphicsItem::paint ( QPainter * painter, const QStyleOptionGraphicsItem *, QWidget * widget )
{
   painter->beginNativePainting();
   ... // здесь рисую: bind, draw, unbind
   painter->endNativePainting();
 
   painter->drawRect( QRect( -100, -100, 200, 200 ) );
   painter->drawText( 100, 100, QString::fromUtf8( "Hello" ) );
   ...
 
   painter->beginNativePainting();
   ... // здесь рисую: bind, draw, unbind
   painter->endNativePainting();
   ...
}
 

отображает без глюков


Название: Re: Отлов бага
Отправлено: Racheengel от Октябрь 05, 2016, 10:27
После того, как выяснилось, что QPainter не особо дружит с OpenGL на некоторых видеокартах (а заранее не знаешь и не подстелишь) - отказались от него, рисуем чистым API.


Название: Re: Отлов бага
Отправлено: Igors от Октябрь 05, 2016, 10:43
отображает без глюков
У меня тоже было все норм пока не перешел на шейдеры. Причем зависит от переменных (атрибутов) шейдера - бред собачий, однако ж..

После того, как выяснилось, что QPainter не особо дружит с OpenGL на некоторых видеокартах (а заранее не знаешь и не подстелишь) - отказались от него, рисуем чистым API.
Помню обсуждали. Оно конечно когда написано да отлажено можно и забыть какой там монстряка  :) А вот начинать с нуля как-то не тянет...


Название: Re: Отлов бага
Отправлено: __Heaven__ от Октябрь 05, 2016, 10:46
После того, как выяснилось, что QPainter не особо дружит с OpenGL на некоторых видеокартах (а заранее не знаешь и не подстелишь) - отказались от него, рисуем чистым API.
Имхо, предсказуемей всего.
У меня артефакты происходят и при снятии аттрибутов с программами. Достаточно поиграть с контекстом. Например у меня каркасные полигоны (а может что-то другое, уже не помню) не позволяют выводить текст


Название: Re: Отлов бага
Отправлено: ssoft от Октябрь 05, 2016, 10:57
У меня тоже было все норм пока не перешел на шейдеры. Причем зависит от переменных (атрибутов) шейдера - бред собачий, однако ж..

Так у меня шейдеров там тоже вагон и маленькая тележка - и вершинные, и фрагментные. Правда вендор в основном NVIDIA.


Название: Re: Отлов бага [рещено]
Отправлено: Igors от Октябрь 05, 2016, 12:31
Надо перед созданием QPainter сделать disableAttributeArray для ВСЕХ, Хрен догадаешься  :'(


Название: Re: Отлов бага [рещено]
Отправлено: __Heaven__ от Октябрь 05, 2016, 18:41
Хрен догадаешься  :'(
необходимо вернуть всё в состояние как было перед рисованием пэинтером.

Также необходимо отключать массивы при смене программы, иначе есть вероятность словить ошибку сегментации во время отрисовки.
Вообще мне на gamedev советовали использовать т.н. stateless rendering. Правда, до реализации я не добрался, но планирую. Вот с помощью этой штуки можно из любого состояния контекста перейти к тому состоянию, которое удовлетворит QPainter.


Название: Re: Отлов бага [рещено]
Отправлено: Igors от Октябрь 06, 2016, 07:16
Также необходимо отключать массивы при смене программы, иначе есть вероятность словить ошибку сегментации во время отрисовки.
Уже добавил для однообразия, хотя неясно почему - рисует верно и без этого

Вообще мне на gamedev советовали использовать т.н. stateless rendering. Правда, до реализации я не добрался, но планирую. Вот с помощью этой штуки можно из любого состояния контекста перейти к тому состоянию, которое удовлетворит QPainter.
Глянул, вроде чисто теория/концепции. Или есть какие-то конкретные наметки?


Название: Re: Отлов бага [рещено]
Отправлено: __Heaven__ от Октябрь 06, 2016, 09:32
Уже добавил для однообразия, хотя неясно почему - рисует верно и без этого
Простое везение. Если я правильно понимаю OpenGL, то скорее всего у вас после компиляции locations массивов совпадают, поэтому контекст не нуждается во включении/выключении массивов.

Вообще мне на gamedev советовали использовать т.н. stateless rendering. Правда, до реализации я не добрался, но планирую. Вот с помощью этой штуки можно из любого состояния контекста перейти к тому состоянию, которое удовлетворит QPainter.
Глянул, вроде чисто теория/концепции. Или есть какие-то конкретные наметки?
Да, я тоже только это нашёл, подозреваю, что для каждой задачи своя реализация, для всего остального - игровые движки :)
Наткнулся на одну простую реализацию, где контекстом управлял синглтон и он имел метод setStates(States), где States структура с элементами контекста (видимость задней стенки полигона, определение передней стенки CW/CCW и т.п.), но мне не совсем понравился этот вариант, потому что 1. синглтон (у меня может быть несколько контекстов), 2. нет учёта шейдерных программ.

Сейчас спасаюсь временным решением для разрешения проблемы включенности массивов. Это обёртка, которая состоит из программы и массивов аттрибутов. Она подаётся в класс управления программами, который в свою очередь откручивает все массивы предыдущей программы, меняет проги и прикручивает новые массивы. Считаю это решение ужасным...


Название: Re: Отлов бага [рещено]
Отправлено: Igors от Октябрь 06, 2016, 13:30
Наткнулся на одну простую реализацию, где контекстом управлял синглтон и он имел метод setStates(States), где States структура с элементами контекста (видимость задней стенки полигона, определение передней стенки CW/CCW и т.п.)
Да, если CULL установлен, QPainter блокируется. Видимо делалось так же как и у меня - ага, QPainter сдох - ищем почему, добавляем нужный restore.

Сейчас спасаюсь временным решением для разрешения проблемы включенности массивов. Это обёртка, которая состоит из программы и массивов аттрибутов. Она подаётся в класс управления программами, который в свою очередь откручивает все массивы предыдущей программы, меняет проги и прикручивает новые массивы. Считаю это решение ужасным...
Я сделал примерно так. Есть manager у него указатель на активный (текущий) шейдер, у шейдера контейнер имен атрибутов. Когда manager получает команду "выбрать шейдер" - тупо отключаются все атрибуты текущего. В итоге только 1 шейдер может иметь активные атрибуты, и перед выходом в QPainter достаточно выполнить то же отключение. Прикручивать новые автоматом не годится, т.к. могут быть не все активны.