C ++ / OpenGL - Rotation d'un rectangle
Question
Pour mon projet, je devais faire pivoter un rectangle. Je pensais que ce serait facile, mais je suis confronté à un comportement imprévisible.
Voici le code:
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();
Le problème, c’est que mon rectangle effectue une traduction quelque part dans la fenêtre tout en effectuant une rotation. En d'autres termes, le rectangle ne conserve pas la position: vec_vehicle_position_.x
et vec_vehicle_position_.y
.
Quel est le problème?
Merci
La solution
Vous devez inverser l'ordre de vos transformations:
glRotatef(30.0f, 0.0f, 0.0f, 1.0f);
glTranslatef(vec_vehicle_position_.x, vec_vehicle_position_.y, 0);
devient
glTranslatef(vec_vehicle_position_.x, vec_vehicle_position_.y, 0);
glRotatef(30.0f, 0.0f, 0.0f, 1.0f);
Autres conseils
Pour élaborer sur les réponses précédentes.
Les transformations dans OpenGL sont effectuées via la multiplication de matrices. Dans votre exemple, vous avez:
M_r_ - la transformation de rotation
M_t_ - la transformation de traduction
v - un sommet
et vous les avez appliqués dans l'ordre:
M_r_ * M_t_ * v
Utilisez des parenthèses pour clarifier:
(M_r_ * (M_t_ * v))
Nous voyons que le sommet est transformé en premier par la matrice la plus proche, qui est dans ce cas la traduction. Cela peut sembler un peu contre-intuitif, car cela vous oblige à spécifier les transformations dans l'ordre inverse de celui où vous souhaitez les appliquer. Mais si vous pensez à la manière dont les transformations sont placées sur la pile de matrice, cela devrait, espérons-le, avoir un peu plus de sens. (la pile est pré-multipliée ensemble).
D'où la nécessité de spécifier les transformations dans l'ordre inverse pour obtenir le résultat souhaité.
L'inertiatic a fourni une très bonne réponse. Du point de vue du code, vos transformations se produiront dans l’ordre inverse de leur apparition. En d'autres termes, les transformations plus proches du code de dessin réel seront appliquées en premier.
Par exemple:
glRotate ();
glTranslate ();
glScale ();
drawMyThing ();
Commencez par mettre à l'échelle votre objet, puis à le traduire, puis à le faire pivoter. Vous devez effectivement "lire votre code à l'envers". pour savoir quelles transformations sont appliquées dans quel ordre. Gardez également à l'esprit l'état de ces transformations lorsque vous insérez et extrayez la pile de vues du modèle.
Assurez-vous que la rotation est appliquée avant la traduction.