Обратите внимание, что в целом я рекомендую использовать математическую библиотеку, такую как 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
должны быть загружены после инициализации матрицы вида, и когда матрица вида изменится, то матрицы не будут учитывать это.