и ориентацию камеры:
void myReshape(int w, int h)
{
glviewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity();
if(w<=h) glFrustum(-2.0, 2.0, -2.0 *(GLfloat)h/(GLfloat)w, 2.0*(GLfloat)h/(GLfloat)w, 2.0, 20.0); eise glFrustum(-2.0, 2.0, -2.0*(GLfloat)w/(GLfloat)h,
2.0* (GLfloat)w/(GLfloat)h, 2.0, 20.0); glMatrixMode(GL_MODELVIEW);
}
Обращаю ваше внимание на то, что аргументы функции glFrustun() задаются с помощью соотношения сторон окна приложения w и h. Теперь остается только добавить в программу main() регистрацию функции с обратным вызовом для обработки событий клавиатуры keys(), и новая версия программы будет готова. Полный текст программы читатель найдет в приложении А. После запуска программы на выполнение вы, несомненно, отметите про себя эффект камеры, движущейся под "чутким руководством" пользователя, более близкое к фотографическому перспективное изображение куба и эффект отсечения, который вносится заданием передней и задней плоскостей отсечения. Обратите внимание на то, что как бы вы ни "ходили" по сцене, куб всегда оказывается в центре кадра.
Существует множество способов организовать движение камеры в пространстве сцены с помощью различных устройств ввода. Если в программе мышь не используется для управления объектами сцены (в нашем примере - вращением куба), то, манипулируя кнопками мыши, можно выполнять, как говорят кинематографисты, "наезд" камеры, поворачивать ее вправо или влево. Для "привязки" камеры обычно используется функция gluLookAt(), но этот эффект можно организовать и другими способами. Один из них - воспользоваться матрицами поворота и сдвига и с их помощью менять в цикле матрицу вида. Если в процессе перемещения камеры не нужно держать в поле зрения определенный объект, этот способ может
5.6. Путешествие с камерой по сцене оказаться более предпочтительным. Можно также организовать в программе специальную переменную для хранения положения камеры и изменять ее по командам пользователя. В таком случае матрицу вида нужно будет вычислять в каждом цикле, начиная с единичной, а не накапливать приращения. В конце концов, способ, который выбирает программист, зависит от специфики приложения. Иногда приходится обращать внимание на эффект накопления ошибки в вычислении матрицы вида при длительном цикле работы с приращениями.