Question

For my project i needed to rotate a rectangle. I thought, that would be easy but i'm getting an unpredictable behavior when running it..

Here is the 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();

The problem with that, is that my rectangle is making a translation somewhere in the window while rotating. In other words, the rectangle doesn't keep the position : vec_vehicle_position_.x and vec_vehicle_position_.y.

What's the problem ?

Thanks

Was it helpful?

Solution

You need to flip the order of your transformations:

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

becomes

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

OTHER TIPS

To elaborate on the previous answers.

Transformations in OpenGL are performed via matrix multiplication. In your example you have:

M_r_ - the rotation transform

M_t_ - the translation transform

v - a vertex

and you had applied them in the order:

M_r_ * M_t_ * v

Using parentheses to clarify:

( M_r_ * ( M_t_ * v ) )

We see that the vertex is transformed by the closer matrix first, which is in this case the translation. It can be a bit counter intuitive because this requires you to specify the transformations in the order opposite of that which you want them applied in. But if you think of how the transforms are placed on the matrix stack it should hopefully make a bit more sense (the stack is pre-multiplied together).

Hence why in order to get your desired result you needed to specify the transforms in the opposite order.

Inertiatic provided a very good response. From a code perspective, your transformations will happen in the reverse order they appear. In other words, transforms closer to the actual drawing code will be applied first.

For example:
glRotate();
glTranslate();
glScale();
drawMyThing();

Will first scale your thing, then translate it, then rotate it. You effectively need to "read your code backwards" to figure out which transforms are being applied in which order. Also keep in mind what the state of these transforms is when you push and pop the model-view stack.

Make sure the rotation is applied before the translation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top