【问题标题】:Understanding glPushMatrix() and glPopMatrix()了解 glPushMatrix() 和 glPopMatrix()
【发布时间】:2014-05-31 15:32:31
【问题描述】:

我有以下代码:

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();的代码上下注释

这样做,下面的代码:

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

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

我似乎无法理解 glPushMatrix()glPopMatrix() 的工作原理。知道如何实现我想要的吗?

【问题讨论】:

    标签: opengl


    【解决方案1】:

    (请注意,这些函数在 OpenGL 3.1+ 中已弃用并删除。如果您正在处理一个严肃的项目,请考虑切换到 GLM 等专用数学库。)

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

    通过推送和弹出矩阵,您可以控制对哪些对象应用哪些变换,以及对对象组应用变换,并轻松反转变换,使它们不会影响其他对象。

    一个例子:

    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 完成的转换在它被调用后被反转,因此它们不会影响任何其他对象。

    【讨论】:

    • 感谢您的解释。我希望drawRobotBaseArm 中的翻译不应用于其他对象。因此,正如您所解释的,当使用push/pop 包围该功能时,我是正确的。问题是函数顶部的平移和旋转(不是drawRobotBaseArm 内部的平移)也应该应用于柱面和磁盘,但在这种情况下,它不是。仅适用于drawRobotBaseArm
    猜你喜欢
    • 2021-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-24
    • 1970-01-01
    相关资源
    最近更新 更多