Russian Qt Forum
Ноябрь 22, 2024, 19:19 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Отлов бага [рещено]  (Прочитано 8754 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Октябрь 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

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

Спасибо
« Последнее редактирование: Октябрь 05, 2016, 12:29 от Igors » Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #1 : Октябрь 05, 2016, 08:35 »

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

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

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

То есть

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

но никогда одновременно совместно.
« Последнее редактирование: Октябрь 05, 2016, 08:38 от ssoft » Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #2 : Октябрь 05, 2016, 09:16 »

Есть такая проблема. Так понимаю, что painter ожидает дефолтный контекст. Получается, что необходимо вернуть всё в состояние как было перед рисованием пэинтером.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Октябрь 05, 2016, 09:37 »

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

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

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

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

Сообщений: 584


Просмотр профиля
« Ответ #4 : Октябрь 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();
   ...
}
 

отображает без глюков
Записан
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #5 : Октябрь 05, 2016, 10:27 »

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

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Октябрь 05, 2016, 10:43 »

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

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

Сообщений: 2130



Просмотр профиля
« Ответ #7 : Октябрь 05, 2016, 10:46 »

После того, как выяснилось, что QPainter не особо дружит с OpenGL на некоторых видеокартах (а заранее не знаешь и не подстелишь) - отказались от него, рисуем чистым API.
Имхо, предсказуемей всего.
У меня артефакты происходят и при снятии аттрибутов с программами. Достаточно поиграть с контекстом. Например у меня каркасные полигоны (а может что-то другое, уже не помню) не позволяют выводить текст
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #8 : Октябрь 05, 2016, 10:57 »

У меня тоже было все норм пока не перешел на шейдеры. Причем зависит от переменных (атрибутов) шейдера - бред собачий, однако ж..

Так у меня шейдеров там тоже вагон и маленькая тележка - и вершинные, и фрагментные. Правда вендор в основном NVIDIA.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Октябрь 05, 2016, 12:31 »

Надо перед созданием QPainter сделать disableAttributeArray для ВСЕХ, Хрен догадаешься  Плачущий
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #10 : Октябрь 05, 2016, 18:41 »

Хрен догадаешься  Плачущий
необходимо вернуть всё в состояние как было перед рисованием пэинтером.

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

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Октябрь 06, 2016, 07:16 »

Также необходимо отключать массивы при смене программы, иначе есть вероятность словить ошибку сегментации во время отрисовки.
Уже добавил для однообразия, хотя неясно почему - рисует верно и без этого

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

Сообщений: 2130



Просмотр профиля
« Ответ #12 : Октябрь 06, 2016, 09:32 »

Уже добавил для однообразия, хотя неясно почему - рисует верно и без этого
Простое везение. Если я правильно понимаю OpenGL, то скорее всего у вас после компиляции locations массивов совпадают, поэтому контекст не нуждается во включении/выключении массивов.

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

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

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Октябрь 06, 2016, 13:30 »

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

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


Страница сгенерирована за 0.098 секунд. Запросов: 23.