C ++ / OpenGL - вращение прямоугольника - PullRequest
5 голосов
/ 17 июня 2009

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

Вот код:

    glPushMatrix();
    glRotatef(30.0f, 0.0f, 0.0f, 1.0f);
    glTranslatef(vec_vehicle_position_.x, vec_vehicle_position_.y, 0);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glBegin(GL_QUADS);

        glTexCoord2f(0.0f, 0.0f);
        glVertex2f(0, 0);
        glTexCoord2f(1.0f, 0.0f);
        glVertex2f(width_sprite_, 0);
        glTexCoord2f(1.0f, 1.0f);
        glVertex2f(width_sprite_, height_sprite_);
        glTexCoord2f(0.0f, 1.0f);
        glVertex2f(0, height_sprite_);

    glEnd();
    glDisable(GL_BLEND);
    glDisable(GL_TEXTURE_2D);
    glPopMatrix();

Проблема в том, что мой прямоугольник переводит где-то в окне во время вращения. Другими словами, прямоугольник не сохраняет позицию: vec_vehicle_position_.x и vec_vehicle_position_.y.

В чем проблема?

Спасибо

Ответы [ 4 ]

10 голосов
/ 17 июня 2009

Вам необходимо изменить порядок ваших преобразований:

glRotatef(30.0f, 0.0f, 0.0f, 1.0f);
glTranslatef(vec_vehicle_position_.x, vec_vehicle_position_.y, 0);

становится

glTranslatef(vec_vehicle_position_.x, vec_vehicle_position_.y, 0);
glRotatef(30.0f, 0.0f, 0.0f, 1.0f);
9 голосов
/ 18 июня 2009

Для уточнения предыдущих ответов.

Преобразования в OpenGL выполняются с помощью умножения матриц. В вашем примере у вас есть:

M_r_ - преобразование вращения

M_t_ - преобразование перевода

v - вершина

и вы применили их в следующем порядке:

M_r_ * M_t_ * v

Использование скобок для уточнения:

(M_r_ * (M_t_ * v))

Мы видим, что вершина сначала преобразуется более близкой матрицей, что в данном случае является переводом. Это может быть немного противоречащим интуиции, потому что это требует, чтобы вы указали преобразования в порядке, противоположном тому, в котором вы хотите их применить. Но если вы подумаете о том, как преобразования размещаются в стеке матриц, то, надеюсь, должно иметь немного больше смысла (стек предварительно умножается вместе).

Следовательно, почему для того, чтобы получить желаемый результат, вам нужно было указать преобразования в обратном порядке.

3 голосов
/ 18 июня 2009

Inertiatic обеспечили очень хороший отклик. С точки зрения кода, ваши преобразования будут происходить в обратном порядке. Другими словами, преобразования, приближенные к фактическому коду чертежа, будут применены первыми.

Например:
glRotate();
glTranslate();
glScale();
drawMyThing();

Сначала масштабирует вашу вещь, затем переводит ее, а затем вращает. Вы фактически должны «прочитать свой код в обратном направлении», чтобы выяснить, какие преобразования применяются в каком порядке. Также имейте в виду, в каком состоянии находятся эти преобразования, когда вы нажимаете и извлекаете стек представления модели.

1 голос
/ 17 июня 2009

Убедитесь, что вращение применяется перед переводом.

...