Прежде всего, вы должны понимать, что в OpenGL нет четких матриц модели и вида.Существует только комбинированная матрица просмотра модели.Так что OpenGL не волнует (или даже не знает), переводите ли вы камеру (что вообще такое камера?) Или объект, поэтому ваше требование не перемещать квадрат полностью искусственно.Хотя это может быть допустимым требованием и различие между преобразованием модели и вида часто очень практично, просто не думайте, что перевод квадрата отличается от перевода камеры с точки зрения OpenGL.
Точно так же вам не обязательно использовать gluLookAt
.Как и glOrtho
, glFrustum
или gluPerspective
, эта функция просто изменяет текущую выбранную матрицу (обычно матрицу просмотра модели), ничем не отличается от функций glTranslate
, glRotate
или glScale
.Функция gluLookAt
полезна, когда вы хотите установить классическую камеру, но ее функциональность также может быть достигнута без проблем вызовами glTranslate
и glRotate
, а иногда (в зависимости от ваших требований) это даже проще, чем искусственносопоставление ваших параметров вида с параметрами gluLookAt
.
Теперь к вашей проблеме, которая действительно легко решается без gluLookAt
: вам нужно переместить камеру в направлении, параллельном плоскости экрана, иэто в свою очередь эквивалентно перемещению камеры в плоскости xy в пространстве обзора (или пространстве камеры, если хотите).И это в свою очередь эквивалентно перемещению сцены в противоположном направлении в плоскости xy в пространстве обзора.
Так что все, что нужно сделать, это
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(x, y, 0.0f);
//camera setup...
Где (x, y) - вектор движения, определенный по событиям касания, соответствующим образом масштабированный (попробуйте, например, разделить координаты касания, которые вы получаете, на размеры экрана или что-то подобное).После этого glTranslate
идут любые другие преобразования камеры или сцены, которые у вас уже есть (будь то gluLookAt
или просто несколько glTranslate/glRotate/glScale
вызовов).Просто убедитесь, что glTranslate(x, y, ...)
- это первое преобразование, которое вы выполняете в матрице вида модели после установки его в идентичность, поскольку мы хотим перемещаться в пространстве вида.
Так что вам даже не нужно gluLookAt
.Из ваших других вопросов я знаю, что ваш код уже выглядит примерно так:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(x, y, z);
glRotatef(...);
...
Так что все, что вам нужно сделать, это вставить значения x и y, определенные по движению касания, в первый вызов glTranslate
(или добавить их).к уже существующим значениям x и y), так как множественные переводы являются совершенно коммутативными.
Для получения более подробной информации о конвейере преобразования OpenGL (который определенно необходим, прежде чем двигаться дальше), вы также можете взглянуть на ответы на этот вопрос .
РЕДАКТИРОВАТЬ: Если вы действительно хотите использовать gluLookAt
(будь то вместо или после вышеупомянутого перевода), здесь некоторые небольшиени слова о его работе.Он определяет камеру с использованием трех трехмерных векторов (передаваемых как 3 последовательных значения каждый).Сначала положение камеры (в вашем случае (0, 0, 2)), затем точка, в которую смотрит камера (в вашем случае (0, 0, 0), но (0, 0, 1) или (0, 0), -42) приведет к той же камере, направление имеет значение).И, наконец, идет восходящий вектор, определяющий приблизительное направление вверх камеры (который дополнительно ортогонализируется с помощью gluLookAt
, чтобы сделать соответствующий ортогональный кадр камеры).
Но так как вектор вверх в вашем случаеось Z, которая также является отрицательным направлением просмотра, это приводит к особой матрице.Вы, вероятно, хотите, чтобы ось Y была направлена вверх, что означало бы вызов
gluLookAt(0,0,2, 0,0,0, 0,1,0);
, что, в свою очередь, эквивалентно простому
glTranslate(0, 0, -2);
, так как вы используете отрицательный z- ось в качестве направления просмотра, что также является значением по умолчанию OpenGL.