Как glPushMatrix () и glPopMatrix () сохраняют сцену одинаковой? - PullRequest
9 голосов
/ 11 августа 2011

Я нашел в сети какой-то код, который переместит поле по экрану, а затем сбросит его после того, как поле достигнет конца экрана.
Вот код:

void display(void) {
  int sign = 1;
  if (lastFrameTime == 0) {
    /*
     * sets lastFrameTime to be the number of milliseconds since
     * Init() was called;
     */
    lastFrameTime = glutGet(GLUT_ELAPSED_TIME);
  }

  int now = glutGet(GLUT_ELAPSED_TIME);
  int elapsedMilliseconds = now - lastFrameTime;
  float elapsedTime = float(elapsedMilliseconds) / 1000.0f;
  lastFrameTime = now;

  int windowWidth = glutGet(GLUT_WINDOW_WIDTH);

  if (boxX > windowWidth) {
    boxX -= windowWidth;
  }
  boxX += (sign)*256.0f * elapsedTime;

  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glPushMatrix();
  //creates a new matrix at the top that we can do things to?
  glTranslatef(boxX, 0.0f, 0.0f);

  /*
   * draw a "quad" (rectangle)
   */
  glBegin(GL_QUADS);
  glVertex2f(0.0f, 0.0f);
  glVertex2f(128.0f, 0.0f);
  glVertex2f(128.0f, 128.0f);
  glVertex2f(0.0f, 128.0f);
  glEnd();
  glPopMatrix();
  //pops that matrix off the stack so we can have a "clean" version to do something next time.?

  glutSwapBuffers();
}

ТеперьЯ понимаю, что glPushMatrix() и glPopMatrix() состоит в том, что glPushMatrix() помещает (или помещает) новую матрицу в стек для вас, чтобы вы могли что-то делать, так что после того, как вы попэто обратно у вас есть "чистый" сланец снова.Вот почему, если я пренебрегаю glPopMatrix() после glEnd(), мой квадрат скорее ускоряется, чем движется с постоянной скоростью.

Однако как получается, что изменения, которые я делаю внутри glPushMatrix() и glPopMatrix() хранятся?Когда я использую glPushMatrix() и вносю изменения в верхнюю матрицу, она визуализирует изменения, но когда я использую glPopMatrix(), разве все эти изменения не пропали?Когда я снова возвращаюсь к «чистому» списку, как получается, что моя коробка перемещается по экрану?

Как записывается состояние этого перевода, если я просто вытащил матрицу снова после внесения изменения?

Ответы [ 3 ]

29 голосов
/ 11 августа 2011

glPushMatrix дублирует матрицу в верхней части стека (вы всегда работаете с верхней). Любое другое преобразование, которое вы делаете, модифицирует эту верхнюю матрицу, дублированную. Когда вы делаете glPopMatrix, мы возвращаемся к исходной матрице.

Например, предположим, вы хотите нарисовать машину. Вы устанавливаете матрицу для рисования кузова автомобиля, назовем это M1. Теперь вы хотите нарисовать одно колесо. Вы можете либо вычислить M2 - матрицу, необходимую для правильного отображения колеса - либо, поскольку колесо относительно кузова автомобиля (таким образом, существует матрица M3 такая, что M2 = M1 * M3), которую вы изменяете M1. Но у машины 4 колеса, вам нужно сохранить копию M1. Вы делаете это, выполняя glPushMatrix, вы получаете обратно копию, выполняя glPopMatrix.

glPushMatrix and glPopMatrix

Когда вы рисуете что-либо на экране, вы даете координаты в пространстве объектов. Чтобы действительно что-то отобразить, эти координаты должны быть преобразованы. Для этого у нас есть несколько матриц.

В примере с колесом у вас есть только одна геометрия колеса, но поскольку вы используете разные матрицы, будет нарисовано четыре колеса. glPushMatrix и glPopMatrix работают только с матрицей, фактические данные вершин хранятся в графическом процессоре, каждый glVertex отправляет туда еще одну, и ее нельзя удалить. Смотрите следующее изображение, матрицы используются только для преобразования координат объекта в мировые координаты (фактически, все матрицы могут быть помещены в стек)

multiple matrices

6 голосов
/ 12 августа 2011

OpenGL - это API рисования. Когда вы вызываете функции рисования, вещи в буквальном смысле рисуются в кадровый буфер в тот самый момент, когда вы выполняете вызов draw - на самом деле OpenGL объединяет все команды внутри себя и обрабатывает их по порядку. Но когда OpenGL собирается обрабатывать эти вызовы рисования, он обращается к кадровому буферу с матрицами, установленными в состояние в этой конкретной позиции в пакете.

Итак, чтобы перефразировать это: OpenGL не выполняет какого-либо управления сценами, он просто рисует вещи в кадровом буфере в порядке и способе, которым вы запускаете команды рисования. Вы отправляете треугольник: OpenGL преобразует и рисует его. Там нет сцены, построенной внутри. Как только вы поняли это, становится тривиальным понять, как стек матриц может делать свое «волшебство».

5 голосов
/ 11 августа 2011

Это только матрица, используемая для преобразования координат, которая восстанавливается glPopMatrix.Не весь кадровый буфер.Кадровый буфер содержит рендеринг четырехугольника, изменение матрицы в дальнейшем не влияет на уже отрендеренный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...