关于opengl:了解glPushMatrix()和glPopMatrix()

Understanding glPushMatrix() and glPopMatrix()

我有以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void drawObj1(){    
    glPushMatrix();
            glTranslatef(rBaseInitPos + (rBaseDim[0] / 2), rBaseDim[1] + baseIncrement + rBaseDim[1] / 2, rBaseDim[2] / 2);
            glRotatef(rBaseArmRotateAngle, 0, 1, 0);
            /*
                    glPushMatrix();
    */
            drawRobotBaseArm();
            /*
                    glPopMatrix();
    */
            glPushMatrix();
                glRotatef(90, 1, 0, 0);
                glEnable(GL_TEXTURE_2D);
                glBindTexture(GL_TEXTURE_2D, rCamouflage[0]);
                gluQuadricTexture(obj, GL_TRUE);
                gluQuadricDrawStyle(obj, GLU_FILL);
                gluDisk(obj, 0, (rBaseDim[0] / 2) - 0.5, 16, 4);
                gluCylinder(obj, (rBaseDim[0] / 2) - 0.5, (rBaseDim[0] / 2) - 0.5, rBaseDim[1] / 2, 16, 4);
                glDisable(GL_TEXTURE_2D);
            glPopMatrix();                      
        glPopMatrix();
    }


void drawScene(){
    glTranslatef(X, Y, Z);
    drawObj0();
    drawObj1();
}

使用上面的代码,由于drawRobotBaseArm();内部只有一个翻译,所以DiskCylinder都被翻译了。由于我不想这样做,因此我取消了drawRobotBaseArm();

上下代码的注释

执行以下操作:

1
2
glTranslatef(rBaseInitPos + (rBaseDim[0] / 2), rBaseDim[1] + baseIncrement + rBaseDim[1] / 2, rBaseDim[2] / 2);
glRotatef(rBaseArmRotateAngle, 0, 1, 0);

仅作用于drawRobotBaseArm();,现在DiskCylinder不会平移和旋转。

我似乎无法理解glPushMatrix()glPopMatrix()的工作方式。知道如何实现所需的内容吗?


(请注意,在OpenGL 3.1中已弃用并删除了这些函数。如果您正在从事认真的项目,请考虑切换到专用的数学库,例如GLM。)

OpenGL保留了一堆矩阵以快速应用和删除转换。 glPushMatrix复制顶部矩阵并将其推入堆栈,而glPopMatrix将顶部矩阵弹出堆栈。所有转换函数(glScaled等)都在顶部矩阵上起作用,并且顶部矩阵是所有渲染命令用来转换其数据的函数。

通过推和弹出矩阵,您可以控制将哪些转换应用于哪些对象,以及将转换应用于对象组,并轻松地反转这些转换,以免影响其他对象。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
glPushMatrix();          // Creates matrix 1 on the top
glTranslated(100, 0, 0); // Applies translation to matrix 1

drawSphere();            // Draws a sphere with translation <100, 0, 0>

glPushMatrix();          // Clones matrix 1 to create matrix 2 and pushes it on the top.
glScaled(2,2,2);         // Scales matrix 2; doesn't touch matrix 1

drawSphere();            // Draws a sphere with both translation <100, 0, 0> and scale <2,2,2>

glPopMatrix();           // Deletes matrix 2; matrix 1 becomes the top.

drawSphere();            // Same as the first sphere.

glPopMarix();            // Deletes matrix 1

在您的示例中,在drawRobotBaseArm周围执行glPush/PopMatrix意味着drawRobotBaseArm进行的转换在调用后会反转,从而不会影响任何其他对象。