Повороты и перемещение
Проблема построения примитивных фигур в том, что они рисуются только в начале координат, т.е. в точке (0,0,0). Для того чтобы изобразить сферу в точке (x0,y0,z0 ), надо переместить начало координат в эту точку, т.е. надо перейти к новым координатам. Эта процедура довольно распространенная при программировании графики и анимации. Часто, бывает очень удобно, сместить координаты в новую точку и повернуть их на требуемый угол.
Для перехода к новым координатам в OpenGL есть две функции:
- glTranslated( x,y,z )
- glRotated(,x0,y0,z0)
Первая функция сдвигает начало системы координат на (x,y,z ). Вторая - поворачивает на угол  против часовой стрелки вокруг вектора (x0,y0,z0). Теперь, стоит сказать еще о двух очень важных функциях:
glPushMatrix(), glPopMatrix()
Они предназначены для сохранения и восстановления текущих координат. Удобно с помощью glPushMatrix() сохранить текущие координаты, потом двигать, вертеть объект, как это необходимо, а после, вызовом glPopMatrix вернуться к старым координатам. Ниже приводится фрагмент кода, который меняет положение конуса:
glPushMatrix(); // сохраняем текущие координаты
glTranslated(1.4,0,0); // сдвигаемся по оси Х на 1.4
glColor3d(0,1,0);
auxSolidSphere(0.5); // рисуем сферу в (1.4,0,0)
// в абсолютных координатах
glTranslated(1,0,0); // еще раз сдвигаемся
glColor3d(0,0,1);
auxSolidSphere(0.3);
glPopMatrix(); // возвращаемся к старой системе координат
glColor3d(1,0,0);
auxSolidSphere(0.75); // рисуем сферу в точке (0,0,0)
// в абсолютных координатах
glPushMatrix(); // сохраняем текущие координаты
glTranslated(1,0,0); // сдвигаемся в точку (1,0,0)
glRotated(75, 1,0,0); // поворачиваем систему координат на 75 градусов
glColor3d(0,1,0);
auxSolidCone(1, 2); // рисуем конус
glPopMatrix(); // возвращаемся к старым координатам
Как видите, конус повернулся в абсолютных координатах. Так что, для того, чтобы нарисовать фигуру не в начале координат, надо:
сохранить текущие координаты
сдвинуть(glTranslated), повернуть(glRotated)
нарисовать то, что хотели
вернуться к старым координатам
Вызовы glPushMatrixglPopMatrix могут быть вложенными, т.е.:
glPushMatrix();
...
glPushMatrix();
glPopMatrix();
...
glPopMatrix();
Естественно число вызовов glPopMatrix должно соответствовать числу вызовов glPushMatrix, иначе сцена может «улететь» в неизвестном направление. Максимально допустимая глубина вложенности glPushMatrix/glPopMatrix определяется следующим образом:
int n;
glGetIntegerv(GL_MAX_MODELVIEW_STACK_DEPTH, &n);
printf("n=%d\n",n);
Спецификация на OpenGL гарантирует, что глубина стека не может быть меньше 32
