Это похоже на матрицы, которые вы использовали бы в матрице проекции, если вы поворачиваете эту матрицу, происходят странные вещи, поскольку вы балуетесь ожиданиями OpenGL в отношении поступающих данных.
Вместо этого вы должны применить вращение к входящим векторам, прежде чем применить проекцию;или, другими словами, вы начинаете с повернутой матрицы и умножаете проекцию поверх нее.
Теперь, если вы используете конвейер с фиксированной функцией, просто используйте рабочий вариант, поместите его в матрицу проекции.А если вы используете шейдеры, поместите его в форму gl_ProjectionMatrix.Существует много алгоритмов шейдеров, которые требуют положения вершин в мировом пространстве;объединение проекции и вида модели проблематично.
Для вашего вида модели в качестве матрицы идентичности используйте следующее:
1 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1
И продолжайте использовать свой рабочий прогноз и применяйте его на втором этапе.
Однако вы бездумно обменивались всеми ненулевыми записями y <-> z, что неправильно:
w 0 0 0
0 h 0 0
0 0 q qn
0 0 -1 0
Правильно было бы поменять местами столбцы y и z:
w 0 0 0
0 q 0 0
0 0 h -1
0 0 qn 0
Теперь, если вы повторно умножите новую «идентичность», приведенную выше, в вашей рабочей проекции вы получите именно это.