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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: выделение объектов мышью без glPerspective  (Прочитано 9290 раз)
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« : Май 28, 2015, 13:39 »

Для старого кода в стиле glTrandlate/rotate было сделать просто: gluUnProject (http://morgeyz.narod.ru/mouse.htm)

Теперь в программе используется QOpenGLFunctions::glUseProgram,    
камера через:
QMatrix4x4 modelView;
modelView.perspective( angleView, ratio , 0.1f, 100.0f );
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #1 : Май 28, 2015, 18:33 »

не пользовался этой функцией, но предполагаю, что вы можете развернуть свою матрицу в const GLdouble modelMatrix[16], а вместо перспективной использовать единичную. Таким образом функция сработает.

С моей стороны есть пара замечаний:
Код
C++ (Qt)
modelView.perspective( angleView, ratio , 0.1f, 100.0f );
Так делать не айс.
Лучше разделять проекцию от модели:
Код
C++ (Qt)
QMatrix4x4 modelView,
          project,
          modelViewProject;
project.perspective( angleView, ratio , 0.1f, 100.0f );
modelViewProject = project * modelView;
 
В программу, которую прикручиваете с помощью glUseProgram теперь будем подставлять modelViewProject вместо modelView.
Соответственно, все повороты, транслэйты делать только с modelView.
При данном подходе можно воспользоваться и gluUnProject без лишних придумываний.

P.S.: А ещё лучше, имхо, найти обратную матрицу modelViewProject, найти координаты тыка в диапозонах [-1..1] и перемножить эти величины. То и будет ваши истинные координаты.
« Последнее редактирование: Май 28, 2015, 18:36 от __Heaven__ » Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #2 : Июнь 02, 2015, 13:00 »

В принципе есть вариант отслеживать буфер глубины по пикселю под мышой, последний объект после которого этот буфер изменился и есть искомый.
Добавил одну функцию glReadPixels(vx, vy, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &vz); и время отрисовки кадра изменилось с 0-1ms до 13ms.

>>С моей стороны есть пара замечаний:
Это прототип, у меня вообще наоборот все получается камера генирирует матрицу перспективы Мп и умножает ее на Мв (матрицу вида), результат отдает модели. Модель результат умножает на матрицу модели Мм, и отдает частям, те умножают на свои матицы Мч (в произвольной вложенности) и в конце эти матрицы записываются в части с текстурами.

Новые координаты получаются Мп*Мв*Мм*Мч*QVector3D(), так как это равно в связи с ассоциативностью матриц этому Мп * (Мв * (Мм * (Мч * QVector3D()))).
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #3 : Июнь 02, 2015, 13:08 »

glReadPixels, имхо, может в будущем сыграть злую шутку. Вдруг вы захотите чистить буфер.
В любом случае вы можете размотать любой пиксель в исходный QVector3D. Ну, дело ваше, как сделать Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Июнь 02, 2015, 14:11 »

В принципе есть вариант отслеживать буфер глубины по пикселю под мышой, последний объект после которого этот буфер изменился и есть искомый.
Добавил одну функцию glReadPixels(vx, vy, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &vz); и время отрисовки кадра изменилось с 0-1ms до 13ms.
Не связывайтесь с glReadPixels, это будет вечный геморрой пока весь этот код не уберете.

Выбор на уровне объектов - далеко не худшее в OpenGL. Вот примерчик. Можно ли так делать "в новом стиле" - хз, я пока с переходом на это новое не спешу. Вообще у Вас доступны вызовы glUnProject и.т.п,? Если да то нужные матрицы найдем (в крайнем случае на вокзале  Улыбающийся)
Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #5 : Июнь 02, 2015, 16:14 »

glReadPixels, имхо, может в будущем сыграть злую шутку. Вдруг вы захотите чистить буфер.
У меня солнце, луна, земля рисуется, после каждого объекта сбрасываю буфер глубины.

Цитировать
В любом случае вы можете размотать любой пиксель в исходный QVector3D. Ну, дело ваше, как сделать Улыбающийся
А как соотнести его с деталью по которой кликнули мышью? Перебор полигонов?
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #6 : Июнь 02, 2015, 16:39 »

В моих задачах мне необходимо вычислять кликнутый полигон. Поэтому делаю перебор. Это быстро и без использования gpu.
Быть может, если объекты простые, как сфера, то можно вычислять точку пересечения клика с каждой из сфер.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Июнь 02, 2015, 16:50 »

Кстати о птичках
Новые координаты получаются Мп*Мв*Мм*Мч*QVector3D(), так как это равно в связи с ассоциативностью матриц этому Мп * (Мв * (Мм * (Мч * QVector3D()))).
Это верно для матриц как они в математике. OpenGL трактует матрицу ширше, напр впихнули туда и перспективу. Поэтому ассоциативность может и не соблюдаться.

В любом случае вы можете размотать любой пиксель в исходный QVector3D.
Координату можно перевести в пиксель (не всегда), но из пикселя можно получить только 2 значения, 3-e (расстояние до цели) не определено. Др словами можно получить только вектор, направление  

Самый простой (и самый тупой) способ - найти вектор камера-цель в мире и парить полигон за полигоном odd-even.  
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #8 : Июнь 02, 2015, 17:54 »

3-e да, нужно сканировать путь клика и искать пересечение. Я занимаюсь этим - достаточно дешёвая операция.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Июнь 02, 2015, 18:27 »

3-e да, нужно сканировать путь клика и искать пересечение. Я занимаюсь этим - достаточно дешёвая операция.
Она совсем не дешевая, спасает то что она разовая

Думается этим приходится заниматься каждому кто хоть как-то работает с OpenGL. И вот мне непонятно, ну вот как же так - снимают с клиента сотни баксов за крутую карту, уверяют что OpenGL - светлое будущее человечества. Но... если бы я спросил на плюсах  "а как сделать массив переменной длины" - через 2 минуты меня бы ткнули носом в std::vector - и это правильно. А здесь (на OpenGL) для совершенно типовой задачи - стандартного решения нема, все велосипедят.

Кстати спрашивал на gamedev (где в лесах много диких обезьян) - ну правда меня интересовал выбор вертексов и фейсов (а не объектов). Ответ по существу: "ну вы как-то это сами сделайте"  Улыбающийся ппц

В общем OpenGL = "Блеск и нищета куртизанок"
Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #10 : Июнь 03, 2015, 12:43 »

Это верно для матриц как они в математике. OpenGL трактует матрицу ширше, напр впихнули туда и перспективу. Поэтому ассоциативность может и не соблюдаться.
перспектика и натягивание почти единичного куба на экранные координаты делаются вне матричного преобразования. Матрица подготавливает координаты, под легкий просчет перспективы.

А если через стенсил буфер пронумеровать все детали? Например я вожу мышкой по модели, а он отображает вспомогательную информацию о детали под курсором?
Правда меня смущает падение fps при использовании glReadPixels(почему?), но можно ограничить вызовы  - только один раз после остановки курсора на Х мл.сек.

через 2 минуты меня бы ткнули носом в std::vector - и это правильно.
От задачи зависит, где то и список лучше будет, а где то new/delete. Тем не менее велосипеды уже есть, выбирай и пользуйся. Qt в этом плане молодцы, столько хороших велосипедиков написали.

А здесь (на OpenGL) для совершенно типовой задачи - стандартного решения нема, все велосипедят.
Кстати спрашивал на gamedev (где в лесах много диких обезьян) - ну правда меня интересовал выбор вертексов и фейсов (а не объектов). Ответ по существу: "ну вы как-то это сами сделайте"  Улыбающийся ппц
В общем OpenGL = "Блеск и нищета куртизанок"
Ага, вот бы QGlWidget::getObject(x,y, номер способа).
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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