Вам необходимо изменить порядок вызовов glTranslate
, поскольку последнее выполненное преобразование является первым, примененным к вершине.Видите, каждое преобразование - это матрица, на которую умножается ваша текущая матрица.Результирующая матрица затем умножается на вершину, чтобы определить ее конечную позицию.
Итак, если у вас есть:
glTranslatef(-60,-20,0); (T1)
glRotatef(10, 0, 0, 1); (R)
glTranslatef(60, 20, 0); (T2)
, а также имеется старая матрица Мо, сохраненная из предыдущего кадра,у вас будет:
M = (((Mo * T1) * R) * T2)
, в конце эта M умножается на каждую вершину Vo, чтобы определить ее конечную позицию:
V = M * Vo
Умножения матриц некоммутативны, но ониявляются ассоциативными, поэтому порядок скобок не имеет значения, и все эти преобразования математически эквивалентны:
V = Mo * T1 * R * (T2 * Vo)
Обратите внимание, что (T2 * Vo) - вершина, преобразованная с помощью T2 (ваш последний перевод).Если мы назовем его V1, то получим:
V = Mo * T1 * (R * V1)
. Видим, что V1, ваша исходная вершина, преобразованная с помощью T2, теперь, в свою очередь, преобразуется вращением R в (R * V1), в результате чего получается другая вершина., теперь переведено, а затем повернуто.Продолжайте решать выражение справа налево, и все преобразования будут применены к вершине в обратном порядке в том месте, где они были «вызваны» в коде OpenGL.
Я полагаю, вы знаете, почему вам нужноtranslate-rotate-untranslate для вращения вокруг желаемой точки, но вы ошиблись, когда сказали, что «вещь» вращается вокруг источника в вашем коде.На самом деле, если вы обратите внимание, вы заметите, что он вращался вокруг точки (-60, -20).
Наконец, вы не используете матрицу вида модели, а выполняете все преобразования, используяматрица перспективы (которая, кстати, работает, поскольку вы не сбрасываете ее каждый кадр, как это делает большинство приложений).Вы не должны делать это, а вместо этого использовать GL_MODELVIEW для такого рода преобразований.Попробуйте завершить функцию инициализации с помощью:
...
Set_Transformations();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glutMainLoop();
}