C++ glPushMatrix() 和 glPopMatrix() 如何保持场景相同?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7031842/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:23:03  来源:igfitidea点击:

How do glPushMatrix() and glPopMatrix() keep the scene the same?

c++openglgraphics

提问by drjrm3

I found some code online which will move a box across the screen, then reset it after the box hits the end of the screen.
Here is the code:

我在网上找到了一些代码,可以在屏幕上移动一个框,然后在框到达屏幕末尾后重置它。
这是代码:

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();
}

Now, the way I understand glPushMatrix()and glPopMatrix()is that glPushMatrix()puts (or pushes) a new matrix on the stack for you to do things to, so that after you pop it back off you have a "clean" slate again. This is why, if I neglect the glPopMatrix()after glEnd(), my square seems to accelerate rather than move at a constant velocity.

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

How is it, however, that the changes I make inside of glPushMatrix()and glPopMatrix()are kept? When I use glPushMatrix()and make a change to the top matrix, it visualizes the changes, but when i use glPopMatrix(), aren't all those changes gone? When I am restored to a "clean" slate again, how is it that my box moves across the screen?

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

How is the state of that translation recorded if i just pop the matrix off again after making the change?

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

采纳答案by Ben Voigt

It's only the matrix, used to transform coordinates, that is restored by glPopMatrix. Not the whole framebuffer. The framebuffer contains the rendering of the quadrilateral, changing the matrix afterward doesn't affect anything already rendered.

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

回答by Mihai Maruseac

glPushMatrixduplicates the matrix on top of the stack (you're always working with the top one). Any other transformation you are doing modifies this top matrix, the duplicated one. When you do glPopMatrixwe are back to the original matrix.

glPushMatrix复制堆栈顶部的矩阵(您始终使用顶部的矩阵)。您正在执行的任何其他转换都会修改此顶部矩阵,即复制的矩阵。当你这样做时,glPopMatrix我们又回到了原来的矩阵。

For example, suppose you want to draw a car. You set up the matrix to draw the body of the car, let's call it M1. Now, you want to draw one wheel. You can either compute M2- the matrix needed for the wheel to be displayed correctly - or, since the wheel is relative to the body of the car (thus, there is a matrix M3such that M2 = M1 * M3) you modify M1. But the car has 4 wheels, you need to keep a copy of M1. You do this by doing a glPushMatrix, you get back the copy by doing a glPopMatrix.

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

glPushMatrix and glPopMatrix

glPushMatrix 和 glPopMatrix

When you draw anything on the screen, you are giving coordinates in object space. To really display something, those coordinates need to be transformed. For that we have some matrices.

当你在屏幕上绘制任何东西时,你是在对象空间中给出坐标。要真正显示某些内容,需要转换这些坐标。为此,我们有一些矩阵。

In the wheel example, you have only one wheel geometry but because you are using different matrices, there will be four wheels drawn. glPushMatrixand glPopMatrixwork only with the matrix, the actual vertex data is kept into the GPU, each glVertexsends another one there and it cannot be removed. See the following image, the matrices are used only for transforming object coordinates to world coordinates (actually, all matrices can be pushed into a stack)

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

multiple matrices

多个矩阵

回答by datenwolf

OpenGL is a drawing API. When you call drawing functions, things are literally drawn to the framebuffer the very moment you issue the draw call -- well actually OpenGL batches up all the commands internally and processes them in order. But when OpenGL is about to process those drawing calls, it will draw to the framebuffer with the matrices set to the state at this specific position in the batch.

OpenGL 是一个绘图 API。当您调用绘图函数时,在您发出绘图调用的那一刻,实际上将事物绘制到帧缓冲区中——实际上,OpenGL 在内部对所有命令进行批处理并按顺序处理它们。但是,当 OpenGL 即将处理这些绘图调用时,它将绘制到帧缓冲区,并将矩阵设置为批处理中此特定位置的状态。

So to reemphase this: OpenGL does not do any kind of scene management, it just draws things to the framebuffer in the order and way you issue the drawing commands. You send a triangle: OpenGL will transform and draw it. There's no scene internally built. Once you understood this it becomes trivial to understand how the matrix stack can do its "magic".

所以再次强调这一点:OpenGL 不进行任何类型的场景管理,它只是按照您发出绘图命令的顺序和方式将事物绘制到帧缓冲区。您发送一个三角形:OpenGL 将转换并绘制它。没有内部构建的场景。一旦你理解了这一点,理解矩阵堆栈如何发挥它的“魔法”就变得微不足道了。