我在网上发现了一些代码,它会在屏幕上移动一个框,然后在框到达屏幕末尾后重置它。
这是代码:
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()
时,是不是所有这些更改都消失了?当我再次恢复到“干净”的状态时,我的盒子如何在屏幕上移动?
如果我在进行更改后再次关闭矩阵,那么该翻译的状态如何记录?
答案 0 :(得分:29)
glPushMatrix
复制堆栈顶部的矩阵(您总是使用顶层矩阵)。您正在进行的任何其他转换都会修改此顶部矩阵,即重复的矩阵。当你glPopMatrix
时,我们会回到原始矩阵。
例如,假设您想要画一辆汽车。你设置矩阵来绘制汽车车身,我们称之为M1
。现在,你想画一个轮子。您可以计算M2
- 车轮正确显示所需的矩阵 - 或者,因为车轮相对于车身(因此,有一个矩阵M3
,使M2 = M1 * M3
1}})您修改M1
。但是这辆车有4个轮子,你需要保留M1
的副本。通过执行glPushMatrix
来执行此操作,您可以通过执行glPopMatrix
来获取副本。
当您在屏幕上绘制任何内容时,您将在对象空间中提供坐标。要真正显示某些内容,需要转换这些坐标。为此我们有一些矩阵。
在车轮示例中,您只有一个车轮几何体,但由于您使用的是不同的矩阵,因此将绘制四个车轮。 glPushMatrix
和glPopMatrix
仅适用于矩阵,实际顶点数据保留在GPU中,每个glVertex
在此处发送另一个,并且无法删除。参见下图,矩阵仅用于将对象坐标转换为世界坐标(实际上,所有矩阵都可以推入堆栈)
答案 1 :(得分:6)
OpenGL是一个绘图API。当你调用绘图函数时,在你发出绘图调用的那一刻,事情就会被绘制到帧缓冲区 - 实际上,OpenGL会在内部批量处理所有命令并按顺序处理它们。但是当OpenGL即将处理这些绘图调用时,它将绘制到帧缓冲区,并将矩阵设置为批处理中此特定位置的状态。
所以重新说一下:OpenGL不进行任何类型的场景管理,它只是按顺序绘制帧缓冲区以及发出绘图命令的方式。你发送一个三角形:OpenGL将转换并绘制它。内部没有场景。一旦理解了这一点,理解矩阵堆栈如何能够实现“神奇”就变得微不足道了。
答案 2 :(得分:5)
它只是用于变换坐标的矩阵,由glPopMatrix
恢复。不是整个帧缓冲。帧缓冲包含四边形的渲染,之后更改矩阵不会影响已渲染的任何内容。