【问题标题】:Seems like glPopMatrix() doesn't reset the transformationmatrix似乎 glPopMatrix() 不会重置 transformationmatrix
【发布时间】:2014-05-15 16:38:39
【问题描述】:

我正在尝试在 OpenGL 中制作太阳系。 每次添加行星时,我都需要弹出转换矩阵,以便从下一个开始。这仅适用于 2 个行星。我可以添加第一个行星(地球)并让它围绕太阳旋转。然后我使用 glPopMatrix() 并添加第二个围绕太阳旋转的行星,这又可以正常工作。但是当我尝试添加第三颗行星并做完全相同的事情时(首先弹出堆栈并使其围绕太阳旋转),看起来transformationMatrix 没有被重置并且第三颗行星围绕第二颗行星旋转,就像第 1 和第 2 颗行星围绕太阳旋转。

这是我的paintGL()的代码:

    void PlanetsView::paintGL ()
{
    this->dayOfYear = (this->dayOfYear+1);
    this->hourOfDay = (this->hourOfDay+1) % 24;

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();

    // store current matrix
    glMatrixMode( GL_MODELVIEW );

    gluLookAt(camPosx ,camPosy ,camPosz,
              camViewx,camViewy,camViewz,
              camUpx, camUpy, camUpz );


    //Draw Axes
    glDisable( GL_LIGHTING );
    glBegin(GL_LINES);
    glColor3f(1.0, 0.0, 0.0);
    glVertex3f(0.0, 0.0, 0.0);
    glVertex3f(10.0, 0.0, 0.0);
    glColor3f(0.0, 1.0, 0.0);
    glVertex3f(0.0, 0.0, 0.0);
    glVertex3f(0.0, 10.0, 0.0);
    glColor3f(0.0, 0.0, 1.0);
    glVertex3f(0.0, 0.0, 0.0);
    glVertex3f(0.0, 0.0, 10.0);
    glEnd();
    glEnable( GL_LIGHTING );

    glPushMatrix();

    // rotate the plane of the elliptic
    glRotated ( 5.0, 1.0, 0.0, 0.0 );

    // draw the sun
    GLfloat diff [] = { 0.7f , 0.5f , 0.0f };
    glMaterialfv ( GL_FRONT, GL_DIFFUSE, diff );

    //glutSolidSphere( 3.0, 25, 25 );
    solidSphere(3.0, 25, 25);

    // rotate the earth around the sun
    glRotated( (GLdouble)(360.0 * dayOfYear /365.0), 0.0, 1.0, 0.0 );
    glTranslated ( 4.0, 0.0, 0.0 );
    // rotate the earth around its axis
    glRotated( (GLdouble)(360.0 * hourOfDay/24.0), 0.0, 1.0, 0.0 );

    // draw the earth
    GLfloat diff2 [] = { 0.2f , 0.2f , 0.8f };
    glMaterialfv ( GL_FRONT, GL_DIFFUSE, diff2 );
    solidSphere(0.3, 25, 25);

    glPopMatrix();

   // rotate the new planet around the sun
    glRotated( (GLdouble)(360.0 * dayOfYear /150.0), 0.0, 1.0, 0.0 );
    glTranslated ( 6.0, 0.0, 0.0 );

    // rotate the new planet around its axis
    glRotated( (GLdouble)(360.0 * hourOfDay/36.0), 0.0, 1.0, 0.0 );


    // draw the new planet
    GLfloat diff3 [] = { 1.0f , 0.0f , 0.0f }; // red color
    glMaterialfv ( GL_FRONT, GL_DIFFUSE, diff3 );
    solidSphere(0.4, 25, 25);

    glPopMatrix();  // looks like this pop doesn't do anything


    /* From here, when adding a 3rd planet, it fails */
    // rotate a 3rd planet around the sun
    glRotated( (GLdouble)(360.0 * dayOfYear /800.0), 0.0, 1.0, 0.0 );
    glTranslated ( 6.0, 0.0, 0.0 );

    // rotate a 3rd planet around its axis
    glRotated( (GLdouble)(360.0 * hourOfDay/12.0), 0.0, 1.0, 0.0 );

    // draw the 3rd planet
    GLfloat diff4 [] = { 1.0f , 1.0f , 0.0f }; // red color
    glMaterialfv ( GL_FRONT, GL_DIFFUSE, diff4 );
    solidSphere(0.3, 25, 25);

    glPopMatrix();

}

这里是solidSphere的代码:

    void solidSphere(GLdouble radius, GLint slices, GLint stacks)
{
    glBegin(GL_LINE_LOOP);
    GLUquadricObj* quadric = gluNewQuadric();

    gluQuadricDrawStyle(quadric, GLU_FILL);
    gluSphere(quadric, radius, slices, stacks);

    gluDeleteQuadric(quadric);
    glEnd();

}

【问题讨论】:

  • 您无法弹出尚未推送的内容。如果您只想重置为单位矩阵,请使用glLoadIdentity()

标签: opengl matrix transformation


【解决方案1】:
glPopMatrix();  // looks like this pop doesn't do anything

正确,这没有任何作用(有意义),你是 下溢矩阵堆栈。

在此之前的几行,您已经从堆栈中弹出了最后一个东西。

如果您的意图是让第二次调用glPopMatrix () 恢复调用glEnable( GL_LIGHTING ) 后存在的矩阵,那么您需要在第一次调用glPopMatrix () 之后立即添加对glPushMatrix () 的调用。并且您需要再次重复该过程,以便您对glPopMatrix () 的第三次调用也不会下溢堆栈。

我觉得你不太清楚堆栈是如何工作的。

【讨论】:

    猜你喜欢
    • 2012-03-12
    • 1970-01-01
    • 2019-08-08
    • 2022-10-24
    • 2017-07-29
    • 1970-01-01
    • 1970-01-01
    • 2021-10-04
    • 2019-07-12
    相关资源
    最近更新 更多