考虑这个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则不然?
答案 0 :(得分:4)
旧样式管道专为场景图使用而设计。当你引入一个新的变换时,它会与当前的变换连接起来,所以为了能够制作场景图,你可以在访问子节点时将当前变换推送到提供的堆栈,应用局部变换,做一些渲染,然后再次关闭变换以返回到父变换。
GL的渲染/光照管道也必须能够理解所使用的矩阵,这就是它被分为“投影”和“模型视图”的原因。
新的样式管道没有做任何事情。您在该管道中正在做的是指定要渲染的确切矩阵。当您指定不同的矩阵时,它只是替换已存在的矩阵。
你的例子相当于:
glLoadIdentity()
glRotate()
所以没有连续的轮换。
如果你想连接,推送,弹出等等,你可以自己实现它。您需要存储前一个矩阵值,然后将其相乘。或者,更新旋转值。
这有很多原因,尤其是可编程管道对于如何转换顶点的定义较少,因此它将必要的矩阵构造留给程序员。也许你甚至没有矩阵,但在着色器中构造变换。