glPushMatrix () glPopMatrix () не работает - PullRequest
0 голосов
/ 16 июня 2019

Я пытаюсь кодировать движение двух объектов независимо, что означает, что оба движутся в двух разных направлениях, это работает, но не может двигаться непрерывно. когда я ставлю glTranslatef() снаружи glPushMatrix() ... glPopMatrix(), он работает нормально.

void display()
{
    glClearColor(0.356, 0.701, 0.0, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

        // if put gltransate() at here the object will moving continuous

    glPushMatrix();
      glTranslatef(.5, 0, 0);
        glBegin(GL_QUADS);
        glColor3f(1.0, 1.0, 1.0);
        glVertex2f(-0.8, 0.5);
        glVertex2f(-0.8, 0.8);
        glVertex2f(-0.2, 0.8);
        glVertex2f(-0.2, 0.5);
      glEnd();
    glPopMatrix();

    glPushMatrix();
          glTranslatef(-.5, 0, 0);
      glBegin(GL_QUADS);
        glColor3f(.0, .0, .0);
        glVertex2f(-0.8, 0.2);
        glVertex2f(-0.8, 0.5);
        glVertex2f(-0.2, 0.5);
        glVertex2f(-0.2, 0.2);
        glEnd();
    glPopMatrix();

}

Я ожидаю, что для первых квадратов объекты будут постоянно двигаться вправо, но кажется, что нужно просто перевести один раз, а затем остановиться в позиции.

1 Ответ

2 голосов
/ 16 июня 2019

Обратите внимание, что в целом я рекомендую использовать математическую библиотеку, такую ​​как OpenGL Matmatics для выполнения матричных вычислений и glLoadMatrix() для загрузки матрицы типа glm::mat4 в текущий матрица.

В любом случае, операция типа glTranslatef() создает новую матрицу и умножает текущую матрицу на новую матрицу. Вот почему последовательные вызовы glTranslatef вызывают прогрессивное «движение».

glPushMatrix / glPopMatrix сохранить и восстановить матрицу в стеке матриц. Таким образом, последовательное движение не может работать, потому что текущая матрица остается неизменной в начале каждого кадра.


Одним из решений было бы сохранить перевод в переменную и увеличить значение переменной:

GLfloat trans_a = 0.0f;
GLflaot trans_b = 0.0f;

void display()
{
    glClearColor(0.356, 0.701, 0.0, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glPushMatrix();

      trans_a += 0.5f;
      glTranslatef(trans_a, 0, 0);

      glBegin(GL_QUADS);
        glColor3f(1.0, 1.0, 1.0);
        glVertex2f(-0.8, 0.5);
        glVertex2f(-0.8, 0.8);
        glVertex2f(-0.2, 0.8);
        glVertex2f(-0.2, 0.5);
      glEnd();
    glPopMatrix();

    glPushMatrix();

      trans_b += 0.5f;
      glTranslatef(trans_b, 0, 0);

      glBegin(GL_QUADS);
        glColor3f(.0, .0, .0);
        glVertex2f(-0.8, 0.2);
        glVertex2f(-0.8, 0.5);
        glVertex2f(-0.2, 0.5);
        glVertex2f(-0.2, 0.2);
      glEnd();
    glPopMatrix();
}

Более обобщенное решение - получить и сохранить текущую матрицу (после перевода) по glGetFloatv(GL_MODELVIEW_MATRIX, ...) и перезагрузить ее по glLoadMatrix():

// init identity matrices
GLfloat mat_a[16] = {1, 0, 0, 0,    0, 1, 0, 0,    0, 0, 1, 0,    0, 0, 0, 1 };
GLfloat mat_b[16] = {1, 0, 0, 0,    0, 1, 0, 0,    0, 0, 1, 0,    0, 0, 0, 1 };

void display()
{
    glClearColor(0.356, 0.701, 0.0, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glPushMatrix();

      glLoadMatrixf(mat_a)
      glTranslatef(0.5f, 0, 0);
      glGetFloatv(GL_MODELVIEW_MATRIX, mat_a);

      glBegin(GL_QUADS);
        glColor3f(1.0, 1.0, 1.0);
        glVertex2f(-0.8, 0.5);
        glVertex2f(-0.8, 0.8);
        glVertex2f(-0.2, 0.8);
        glVertex2f(-0.2, 0.5);
      glEnd();
    glPopMatrix();

    glPushMatrix();

      glLoadMatrixf(mat_b)
      glTranslatef(0.5f, 0, 0);
      glGetFloatv(GL_MODELVIEW_MATRIX, mat_b);

      glBegin(GL_QUADS);
        glColor3f(.0, .0, .0);
        glVertex2f(-0.8, 0.2);
        glVertex2f(-0.8, 0.5);
        glVertex2f(-0.2, 0.5);
        glVertex2f(-0.2, 0.2);
      glEnd();
    glPopMatrix();
}

Обратите внимание, что в этом случае mat_a и mat_b должны быть загружены после инициализации матрицы вида, и когда матрица вида изменится, то матрицы не будут учитывать это.

...