NimuraF
@NimuraF

Как получать и обрабатывать координаты мыши в окне OpenGL?

Решил побаловаться различными кнопками/чекбоксами на OpenGL, собственно, возник резонный вопрос, а каким образом без GLUT можно получать и обрабатывать координаты в окне OpenGL?

Пробовал через GetCursorPos, однако он берёт за основу координаты всего рабочего стола, а не окна OpenGL, так же не совсем понимаю каким образом преобразовывать координаты от GetCursorPos в координаты OpenGL.
  • Вопрос задан
  • 758 просмотров
Решения вопроса 1
@MarkusD Куратор тега C++
все время мелю чепуху :)
По координатам мышки пойдем от самого верха, операционной системы, и до мирового пространства, в котором рисуется твоя сцена.

Самое первое - это не нужно именно получать координаты курсора в момент его обработки. Нужно реагировать на сообщения о перемещении курсора по окну и запоминать координаты в его клиентской области, в которой у тебя и происходит отрисовка сцены.
Но если очень хочется, то на WinAPI можно использовать GetCursorPos[?] и ScreenToClient[?] чтобы на месте получить координаты курсора в клиентской области окна.
На этом этапе нужно принять во внимание то, в какой координатной системе считаются координаты курсора.
Например, в WinAPI координатная система окна выглядит так. И именно в ней считаются координаты курсора.

Все следующие этапы стоит рассматривать как переходы из одного пространства в другое. Числа могут быть одинаковыми, но ценность перехода именно в том, чтобы перевести эти числа из одного пространства в другое.

Следующим этапом будет переход от клиентской области к области вьюпорта. Этот переход делается через дополненную 2х2 матрицу трансформаций 2D-пространства. Ее важно использовать везде, т.к. это позволит заложить фундамент однообразного перехода из пространства клиентской области экрана в пространство координатной системы камеры.
Что важно на этом этапе. Пространство вьюпорта и пространство камеры связаны через пространство нормализованных координат области отсечения. В разных GAPI пространство области отсечения представлено по-разному. И пространство вьюпорта тоже по-разному представлено в разных GAPI.
Например, в OpenGL координатная система вьюпорта выглядит так.
Еще на этом этапе нужно заложить переход от точки к лучу, т.к. вьюпорт уже имеет объем. Для этого координаты курсора нужно дополнить минимальной и максимальной глубиной вьюпорта, получив уже две точки координат курсора.
В качестве примера такого преобразования можно взять код функции D3DXVec3Unproject прямо из Wine. Там делается правильный и простой переход из пространства клиентской области окна в пространство области отсечения OpenGL через пространство вьюпорта.

От пространства области отсечения координаты курсора нужно перевести в пространство сцены.
Матрица View-Projection переводит геометрию из системы координат пространства сцены в систему координат области отсечения. Значит, чтобы сделать переход из области отсечения в пространство сцены, нужно использовать инверсию матрицы View-Projection.

Переведенная в пространство сцены пара точек формирует отрезок. Нужно запомнить точку с дополнением минимальной глубины вьюпорта, обозначить ее как источник луча курсора. Вторую точку нужно локализовать относительно первой и нормализовать. Это будет направление луча.
Этим лучом можно будет щупать всю сцену, любой объект, переводя его координаты к локальной системе объекта и проверяя на пересечения.
Переход от пространства сцены в локальное пространство объекта производится через умножение луча на обратную мировую матрицу этого объекта.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
VoidVolker
@VoidVolker
Dark side eye. А у нас печеньки! А у вас?
Пробовал через GetCursorPos, однако он берёт за основу координаты всего рабочего стола, а не окна OpenGL, так же не совсем понимаю каким образом преобразовывать координаты от GetCursorPos в координаты OpenGL.

Конвертацией системы координат - для этого потребуется еще положение и размер окна.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы