1

Consider this OpenGL ES 1.1 code, called every frame:

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

//... enable, point, draw vertices

glPopMatrix();

All well and good. Now if I remove the push/pop, I get continuous rotation animation, which makes sense.

However, in ES 2.0, here is the equivalent effect:

 //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

This also creates the proper image, but despite nothing equivalent to a "push/pop" technique, it does not continuously rotate. Why does the 2.0 not continuous rotate, while the 1.1 does?

Or phrased another way, why does 1.1 require the push/pop to prevent continuous animation, while 2.0 does not?

4

1 回答 1

4

旧式管道是为场景图使用而设计的。当您引入一个新变换时,它会与当前变换连接,因此为了能够制作场景图,您可以在访问子节点时将当前变换推送到提供的堆栈中,应用本地变换,做一些渲染,然后再次弹出变换以返回父变换。

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

新风格的管道不会做任何事情。您在该管道中所做的是指定要渲染的确切矩阵。当您指定不同的矩阵时,它只是替换已经存在的任何内容。

您的示例等效于执行以下操作:

glLoadIdentity()
glRotate()

所以没有连续的旋转。

如果您想要连接、推送、弹出等,则由您自己实现。您需要存储前一个矩阵值,并将其相乘。或者,更新旋转值。

造成这种情况的原因有很多,其中最重要的是可编程管道对如何转换顶点的定义不太严格,因此它将必要矩阵的构建留给了程序员。也许您甚至没有矩阵,而是在着色器中构造变换。

于 2012-12-27T08:03:30.123 回答