Как мне найти проекционную матрицу, которая эквивалентна ортографической матрице, но дает перспективу, когда не в плоскости xy? - PullRequest
2 голосов
/ 06 марта 2012

Я бездельничаю в программе, которая выполняет весь рендеринг, используя матрицу, установленную gluOrtho2D (). Я хотел бы повернуть конкретную текстуру вокруг оси y (0,1,0), чтобы она выглядела так, как будто исходная матрица была предоставлена ​​функцией gluPerspective (). Я понимаю, что это невозможно с ортогональной проекционной матрицей и что мне придется установить новую матрицу перспективной проекции. Я хочу, чтобы текстуры, которые я рисую, выглядели точно так же, как при рисовании с помощью ортогональной матрицы, за исключением случаев, когда я поворачивал их вокруг оси y.

Итак, подведем итог:
Как найти матрицу проекционной перспективы, которая эквивалентна заданной ортографической матрице, когда фигуры нарисованы в плоскости xy, но дает перспективу, когда она не находится в плоскости xy?

Ответы [ 3 ]

4 голосов
/ 06 марта 2012

По сути, я понимаю: вам нужна матрица перспективы, которая дает такое же изображение, что и ортографическая проекция, когда объект лежит в плоскости XY.

Итак, начнем: Вы хотите нарисовать свою плоскость в плоскости XY, и у вас было gluOrtho2D(-w, w, -h, h); (асимметричная ортографическая проекция немного сложнее, если вам это нужно, тогда скажите так).Что вам нужно сделать сейчас:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(2 * atan(h / 2)  * 180.0 / PI, w / h, 1, 3);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -2);

То, что я здесь сделал, - это сопоставление центра усеченного проекционного вида на участке плоскости XY, который был виден в ортографической проекции.

Возьмите графики проекций и немного математики, и вы можете сделать это самостоятельно:)


В качестве напоминания я оставлю здесь свой ответ на старый вопрос.

Либо у вас есть орто или перспективная проекция.Вы должны решить за один.Вы не получите перспективу, вращаясь по любой оси.

Зачем вам нужно менять целую программу, просто чтобы изменить режим проецирования?

Одно из возможных решений: я предполагаю, что старый GL с другимматричные режимы и т. д.:

glMatrixMode(GL_PROJECTION); //switch to projection matrix mode
glPushMatrix(); //push the old matrix
glLoadIdentity();
//apply the perspective projection
//do your rendering
glPopMatrix(); //pop the old matrix

С более новой схемой GL вам придется делать большую часть этого самостоятельно, но это должно быть легко.

0 голосов
/ 08 июля 2013

Возможно иметь эффект перспективы, то есть вращать вокруг оси x или y, даже если ваша матрица проекции является орфографической, хитрость заключается в том, чтобы умножить матрицу вашего взгляда на эту магическую матрицу до / после любого другого преобразования вида:

// The matrix is
// -z,  0,  x,  0
//  0, -z,  y,  0
//  0,  0,  1,  0
//  0,  0,  1, -z

где:

  • x - это половина ширины области просмотра,
  • y - половина высоты окна просмотра,
  • z может быть любым отрицательным числом, кроме -0.

Несколько заметок:

  1. если вы вызываете glRotate *, эта матрица идет первой, поскольку эти встроенные вызовы являются умножением правой рукой. если вы отслеживаете свою собственную матрицу представления, используя левое умножение, как предложено в учебниках, эта матрица идет последней. В любом случае, эта матрица будет умножена на матрицу вашего орфографического проекта, так что вы также можете предварительно рассчитать
  2. z - это фактически смоделированная глубина z, поэтому чем она больше по величине, тем дальше объекты, как следствие, вращение больше похоже на орфографию. Z не может быть положительным, потому что это сделает w в NDC отрицательным, OpenGL не позволяет этого, оно будет обрезано, поэтому ничто не будет рисовать
  3. В конце концов, нет никакой магии, эта матрица является просто компенсацией, после того как вы выполните: M (орто) X M (магия), вы получаете перспективную матрицу
  4. Этот трюк крайне важен, если 99% вашего кода написано для орфографии, но только одно или два места требуют эффекта перспективы, тогда вам не нужно переключаться между двумя режимами, если вы используете фиксированный конвейер, GL_PROJECTION_MATRIX останется неизменным
  5. эта матрица взята из Android Open Source Project, так что, надеюсь, это даст вам большую уверенность
0 голосов
/ 06 марта 2012

Возможно ли это каким-то простым способом без необходимости конвертировать всю программу в использование gluPerspective ()?

Я уже устал говорить об этом, но:

Проекция не является чем-то определенным один раз, а затем применяется во всем процессе рендеринга.Вы можете поменять его в любое время, и любая улучшенная схема рендеринга сделает это несколько раз в течение одного кадра.

Я думаю, что большинство новичков смущены этим:

reshape(width, height):
    glViewport(0,0,width,height)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    projection_setup()

Они видятпроекция выполняется в функции изменения формы и думаю, что это единственное место, где это можно сделать.Пожалуйста, говорите со мной: Матрица проекции - это просто некое состояние, используемое для рисования, как и все остальное.Его можно изменить так же легко, как текущий цвет или текстуру.

Просто установите необходимую вам проекцию для определенной последовательности команд рисования, как вам это нужно, прямо перед рисованием.

...