В OpenGL в Delphi я пытаюсь вычислить, какая часть сцены видима, находя левый, правый, верхний и нижний экстенты области просмотра в ортогональной проекции. Это приведет к тому, что некоторые взаимодействия с мышью будут казаться 1-к-1. У меня нет большого доступа к коду, который устанавливает матрицу ортографической проекции, но я знаю, что он вызывает glOrtho (...) для установки матрицы проекции.
Мне нужно иметь возможность взять декартову плоскость (не визуализированную многоугольную плоскость), а затем вычислить левый, правый, верхний и нижний края области просмотра из любой информации, которую может предоставить opengl (меня не волнует передние и задние плоскости отсечения). У меня нет доступа к коду, который устанавливает объем просмотра (используя библиотеку glScene для Delphi), поэтому единственная информация, которую я могу использовать, чтобы найти эту информацию (насколько мне известно), это
glGet(GL_PROJECTION_MATRIX, @projectionMatrix);
Основываясь на документации в http://www.talisman.org/opengl-1.1/Reference/glOrtho.html, Я решил, что могу сделать некоторую математику, чтобы вычислить, каковы были левый, правый, верхний и нижний экстенты для ближней плоскости (чего в орто-режиме достаточно) (см. Мой код ниже). Однако, когда я на самом деле смотрю на значения, которые я извлекаю из glGet, я вижу матрицу со значениями, которые не соответствуют описанию в приведенной выше ссылке на документацию (см. Данные матрицы ниже). С такими разочаровывающими числами у меня есть сомнения относительно того, правильно ли я использую glGet, и могу ли я действительно полагаться на эти числа, чтобы дать мне левый / правый / верхний / нижний экстенты видимого тома. Полагаю, я тоже мог совершить ошибку в Delphi, но я не знаю, что это будет.
В этом конкретном случае плоскость ориентирована так, чтобы смотреть прямо в камеру, а камера имеет ортогональную проекцию. Я не полностью контролирую настройку матрицы проекции, поэтому я надеялся, что смогу вычислить левый край как
left = 2 / (A * (tx - 1)/(tx+1) - 1)
Где A и tx извлекаются из матрицы проекции, как показано в http://www.talisman.org/opengl-1.1/Reference/glOrtho.html (я не показываю, как я вывел формулу выше, поэтому она может быть неверной - сейчас она дает ответ - INF).
Код, который я использовал для получения значений матрицы проекции, выглядит следующим образом:
var
projectionMatrix: TMatrix;
Left, Right, Top, Bottom: Single;
A, B, C, tx, ty, tz: Single;
begin
A := projectionMatrix[0][0];
B := projectionMatrix[1][1];
C := projectionMatrix[2][2];
tx := projectionMatrix[0][3];
ty := projectionMatrix[1][3];
tz := projectionMatrix[2][3];
Left := 2 / (A * ((tx - 1) / (tx + 1) - 1));
ShowMessage(FloatToStr(A));
//etc...
Значения матрицы, которые я вижу, примерно такие:
[0] (0, 1.7436188636e-39, 6.4310754487e+37, 1.3822464104e-39)
[1] (3.8535707769e-43, 1.4012984643e-45, 0, 2.8086960027e+32)
[2] (-4.20345941e+17, 0, 1.7437029415e-39, 2.8086960027e+32)
[3] (1.7437645986e-39, 6.4311900443e+37, +NAN, 1.7437645986e-39)
[Изменить]
glScene имеет следующие объявления:
TMatrix = THomogeneousFltMatrix;
THomogeneousFltMatrix = TMatrix4f;
TMatrix4f = array[0..3] of TVector4f;
TVector4f = array[0..3] of single;
[Изменить]
Если я изменю матрицу проекции на массив из 16 значений, вот что произойдет:
var
projectionMatrix, modelviewMatrix: array[0..16] of single;
begin
...
glGetFloatv(GL_PROJECTION_MATRIX, @projectionMatrix);
...
результирующий массив - это элементы с 0 по 16, которые по-прежнему выглядят неправильно.
projectionMatrix (5.9208279286e-39,
-1536643072, 1,2429653406, -1.2128044229e-11, 2,8763115406, 0, 4,728515625, 1.7430022923e-39, 6.5138089186e + 37, 30 + -3.7955583126e, -2,4000201225, -3.7955583126e + 30, 2,4000201225, -1.2128044229e-11, 2,6263115406, -1,2128044229e-11, -2,6263115406)