glPushMatrix()和glPopMatrix()如何使场景保持一致?

drj*_*rm3 9 c++ opengl graphics

我在网上发现了一些代码,它会在屏幕上移动一个框,然后在框到达屏幕末尾后重置它.
这是代码:

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();
}
Run Code Online (Sandbox Code Playgroud)

现在,我理解的方式glPushMatrix()glPopMatrix()glPushMatrix()看跌期权(或推)堆栈为你做的事情,在一个新的矩阵,这样你的流行回来后关闭你再有一个"干净"的石板.这就是为什么,如果我忽略了glPopMatrix()glEnd(),我的方块似乎加速而不是以恒定的速度移动.

然而,我在内部glPushMatrix()glPopMatrix()保留的变化是怎样的呢?当我使用glPushMatrix()并对顶部矩阵进行更改时,它会显示更改,但是当我使用时glPopMatrix(),是不是所有这些更改都消失了?当我再次恢复到"干净"的状态时,我的盒子如何在屏幕上移动?

如果我在进行更改后再次关闭矩阵,那么该翻译的状态如何记录?

Mih*_*eac 29

glPushMatrix复制堆栈顶部的矩阵(您总是使用顶层矩阵).您正在进行的任何其他转换都会修改此顶部矩阵,即重复的矩阵.当你这样做时,glPopMatrix我们回到原始矩阵.

例如,假设您想要画一辆汽车.你设置矩阵来绘制汽车的车身,让我们称之为M1.现在,你想画一个轮子.您可以计算M2-要正确显示所需要的车轮上的矩阵-或者,由于车轮相对于汽车的车身(因此,是一个矩阵M3这样M2 = M1 * M3)你修改M1.但是这辆车有4个轮子,你需要保留一份副本M1.你通过做一个这样做glPushMatrix,你通过做一个回复副本glPopMatrix.

glPushMatrix和glPopMatrix

当您在屏幕上绘制任何内容时,您将在对象空间中提供坐标.要真正显示某些内容,需要转换这些坐标.为此,我们有一些矩阵.

在车轮示例中,您只有一个车轮几何体,但由于您使用的是不同的矩阵,因此将绘制四个车轮.glPushMatrix并且glPopMatrix仅使用矩阵,实际的顶点数据保存在GPU中,每个都glVertex在那里发送另一个并且无法删除.参见下图,矩阵仅用于将对象坐标转换为世界坐标(实际上,所有矩阵都可以推入堆栈)

多个矩阵


dat*_*olf 6

OpenGL是一个绘图API.当你调用绘图功能,事情是从字面上绘制到帧缓冲区发出绘制调用非常时刻 - 以及实际的OpenGL批了所有的内部命令,为了对其进行处理.但是当OpenGL即将处理这些绘图调用时,它将绘制到帧缓冲区,并将矩阵设置为批处理中此特定位置的状态.

因此,重新考虑一下:OpenGL不进行任何类型的场景管理,它只是按顺序将帧内容绘制到帧缓冲区以及发出绘图命令的方式.你发送一个三角形:OpenGL将转换并绘制它.内部没有场景.一旦你理解了这一点,理解矩阵堆栈如何能够实现其"神奇"就变得微不足道了.


Ben*_*igt 5

它只是用于变换坐标的矩阵,它被恢复glPopMatrix.不是整个帧缓冲.帧缓冲区包含四边形的渲染,之后更改矩阵不会影响已渲染的任何内容.