为什么OpenGL ES 2.0中不需要push / pop矩阵等价?

时间:2012-12-27 07:52:05

标签: c++ opengl-es opengl-es-2.0

考虑这个OpenGL ES 1.1代码,称为每一帧:

glPushMatrix();
glRotatef(m_currentAngle, 0, 0, 1);

//... enable, point, draw vertices

glPopMatrix();

一切都很好。现在,如果我删除了push / pop,我会得到连续的旋转动画,这很有意义。

然而,在ES 2.0中,这是等效的效果:

 //no glRotate so doing this:
float radians = m_currentAngle * 3.14159f / 180.0f;
float s = std::sin(radians);
float c = std::cos(radians);
float zRotation[16] = {
    c, s, 0, 0,
    -s, c, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1
};
GLint modelviewUniform = glGetUniformLocation(m_simpleProgram, "Modelview");
glUniformMatrix4fv(modelviewUniform, 1, 0, &zRotation[0]);

//... then enable, point and draw vertices

这也创造了正确的图像,但是尽管没有任何“推/弹”技术,它连续旋转。为什么2.0不连续旋转,而1.1呢?

或者说另一种方式,为什么1.1要求push / pop来阻止连续动画,而2.0则不然?

1 个答案:

答案 0 :(得分:4)

旧样式管道专为场景图使用而设计。当你引入一个新的变换时,它会与当前的变换连接起来,所以为了能够制作场景图,你可以在访问子节点时将当前变换推送到提供的堆栈,应用局部变换,做一些渲染,然后再次关闭变换以返回到父变换。

GL的渲染/光照管道也必须能够理解所使用的矩阵,这就是它被分为“投影”和“模型视图”的原因。

新的样式管道没有做任何事情。您在该管道中正在做的是指定要渲染的确切矩阵。当您指定不同的矩阵时,它只是替换已存在的矩阵。

你的例子相当于:

glLoadIdentity()
glRotate()

所以没有连续的轮换。

如果你想连接,推送,弹出等等,你可以自己实现它。您需要存储前一个矩阵值,然后将其相乘。或者,更新旋转值。

这有很多原因,尤其是可编程管道对于如何转换顶点的定义较少,因此它将必要的矩阵构造留给程序员。也许你甚至没有矩阵,但在着色器中构造变换。