Странная проблема здесь, я конвертировал свой текущий проект из собственных классов матрицы / векторов Qt в Eigen, но я столкнулся с проблемой, которую я не могу решить.
Я вычисляю MVP для шейдера следующим образом:
DiagonalMatrix< double, 4 > diag( Vector4d( 1.0, 1.0, -1.0, 1.0 ) );
scrMatrix_.noalias() = projMatrix_ * diag * camMatrix_.inverse();
Матрица diag
инвертирует ось Z, потому что все мои математические данные видят, что вектор прицеливания камеры указывает на экран, но OpenGL делает обратное. В любом случае, это работает, потому что сторона просмотра OpenGL отображается и работает нормально.
Другая сторона моего вывода в окне просмотра - рисование 2D-оверлеев через систему Qt paintEvent()
, например, маркировка сетки. Поэтому я использую ту же матрицу, чтобы найти трехмерное местоположение в пространстве клипа камеры:
Vector4d outVec( scrMatrix_ * ( Vector4d() << inVec, 1.0 ).finished() );
За исключением случаев, когда я получаю совершенно неверные результаты:
inVec: 0 0 10
outVec: 11.9406 -7.20796
В этом примере я ожидал чего-то большего, чем outVec: 0.55 -0.15
. Мой вершинный шейдер GLSL выполняет вычисления следующим образом:
gl_Position = scrMatrix_ * transform * vec4( inVec, 1.0 );
В приведенных выше примерах transform
- это тождество, поэтому я не вижу никакой разницы между этими двумя проекциями, и все же результаты совершенно разные! Я знаю, что это длинный выстрел, но кто-нибудь может увидеть, где я иду не так?
Обновление:
Я переопределил старый (рабочий) код Qt для сравнения:
QVector3D qvec( vector( 0 ), vector( 1 ), vector( 2 ) );
QMatrix4x4 qmat( Affine3d( scrMatrix_ ).data() );
QPointF pnt = ( qvec * qmat ).toPointF() / 2.0;
Vs:
Vector4d vec( scrMatrix_ * ( Vector4d() << vector, 1.0 ).finished() );
QPointF pnt = QPointF( vec( 0 ), vec( 1 ) ) / 2.0;
Мне они идентичны, но работает только версия Qt!