C ++ / OpenGL преобразует мировые координаты в экранные (2D) координаты - PullRequest
15 голосов
/ 13 декабря 2011

Я делаю игру в OpenGL, где у меня есть несколько объектов в мировом пространстве. Я хочу создать функцию, в которой я могу взять местоположение объекта (3D), преобразовать его в местоположение на экране (2D) и вернуть его.

Я знаю трехмерное местоположение объекта, матрицу проекции и матрицу вида в следующих переменных:

Matrix projectionMatrix;
Matrix viewMatrix;
Vector3 point3D;

1 Ответ

35 голосов
/ 13 декабря 2011

Чтобы сделать это преобразование, вы должны сначала занять свои позиции в пространстве модели и преобразовать их в пространство клипа. Это делается с помощью умножения матриц. Я буду использовать код в стиле GLSL, чтобы было понятно, что я делаю:

vec4 clipSpacePos = projectionMatrix * (viewMatrix * vec4(point3D, 1.0));

Обратите внимание, как я преобразовываю ваш трехмерный вектор в четырехмерный вектор перед умножением. Это необходимо, потому что матрицы имеют размер 4x4, и вы не можете умножить матрицу 4x4 на трехмерный вектор. Вам нужен четвертый компонент.

Следующим шагом является преобразование этой позиции из пространства клипа в нормализованное пространство координат устройства (пространство NDC). Пространство NDC находится в диапазоне [-1, 1] по всем трем осям. Это делается путем деления первых трех координат на четвертые:

vec3 ndcSpacePos = clipSpacePos.xyz / clipSpacePos.w;

Очевидно, что если clipSpacePos.w равно нулю, у вас есть проблема, поэтому вы должны проверить это заранее. Если это ноль, то это означает, что объект находится в плоскости проекции; это глубина пространства просмотра равна нулю. И такие вершины автоматически обрезаются OpenGL.

Следующим шагом является преобразование из этого пространства [-1, 1] в координаты относительно окна. Это требует использования значений, которые вы передали glViewport. Первые два параметра - это смещение от нижнего левого угла окна (vec2 viewOffset), а вторые два параметра - это ширина / высота области просмотра (vec2 viewSize). Учитывая это, позиция оконного пространства:

vec2 windowSpacePos = ((ndcSpacePos.xy + 1.0) / 2.0) * viewSize + viewOffset;

И это так далеко, как вы идете. Помните: пространство окна OpenGL относится к внизу слева окна, а не к верхнему левому углу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...