TIGSource Forums

Developer => Technical => Topic started by: kurtss on May 12, 2013, 12:13:08 PM



Title: In which order should I do these following transformations?
Post by: kurtss on May 12, 2013, 12:13:08 PM
So I draw images using vertexes and the like in OpenGL (LWJGL specifically.)

I currently, in this order:

Translate
Rotate
Scale
Draw

Is this the right order? I'm only using 2D coordinates if that changes anything. My code is as follows:

Code:
GL11.glPushMatrix();
tex.bind();
enableTexturing();
GL11.glTranslatef(x + (xflip ? tex.getImageWidth() : 0), y + (yflip ? tex.getImageHeight() : 0), 0);
if(rot != 0){
GL11.glTranslatef((tex.getImageWidth() / 2) * xScale, (tex.getImageHeight() / 2) * yScale, 0);
GL11.glRotatef(rot, 0, 0, 1);
GL11.glTranslatef(-(tex.getImageWidth() / 2) * xScale, -(tex.getImageHeight() / 2) * yScale, 0);
}
if(xflip) GL11.glScalef(-1, 1, 1);
if(yflip) GL11.glScalef(1, -1, 1);
if(xScale != 1 || yScale != 1){
if(xScale != 1) GL11.glTranslatef(-tex.getImageWidth() * xScale / 2, 0, 0);
if(yScale != 1) GL11.glTranslatef(0, -tex.getImageHeight() * yScale / 2, 0);
GL11.glScalef(xScale, yScale, 0);
}
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0f, 0f);
GL11.glVertex2f(0, 0);
GL11.glTexCoord2f(tex.getWidth(), 0f);
GL11.glVertex2f(tex.getImageWidth(), 0);
GL11.glTexCoord2f(tex.getWidth(), tex.getHeight());
GL11.glVertex2f(tex.getImageWidth(), tex.getImageHeight());
GL11.glTexCoord2f(0f, tex.getHeight());
GL11.glVertex2f(0, tex.getImageHeight());
GL11.glEnd();
disableTexturing();
GL11.glPopMatrix();


Title: Re: In which order should I do these following transformations?
Post by: JakobProgsch on May 12, 2013, 01:30:52 PM
Transform in the order you need? (no one can tell you that ;)). Just be aware how the transforms work...
If you write Translate, Rotate, Scale you get a matrix that is T*R*S. So if you then multiply that by a vector you get T*R*S*v you essentially get (T*(R*(S*v))) so the Scaling is applied "first".


Title: Re: In which order should I do these following transformations?
Post by: Evan Balster on May 12, 2013, 02:33:56 PM
If I'm not mistaken, OpenGL does the multiplications the other way.  Generally it's desirable to rotate and scale an object (order doesn't particularly matter here) and then translate it.


Title: Re: In which order should I do these following transformations?
Post by: Loop Gain on May 12, 2013, 05:27:21 PM
It's a bit general, but you might find the section entitled "Viewing and Modeling Transformations" about a quarter of the way down on this page (http://fly.cc.fer.hr/~unreal/theredbook/chapter03.html) (from an archived copy of an older version of the OpenGL Programming Guide) useful.

The "correct" order in which to apply a set of transformations depends on whether you're thinking about the transformations from the perspective of a global coordinate system that's unaffected by the transformations or a local one that's attached to the object being transformed (and thus affected by any transformations applied to the object).

Here's a quote from the page I linked to above that goes into a bit more detail:



Thus, if you like to think in terms of a grand, fixed coordinate system - in which matrix multiplications affect the position, orientation, and scaling of your model - you have to think of the multiplications as occurring in the opposite order from how they appear in the code. Using the simple example discussed in Figure 3-4 (a rotation about the origin and a translation along the x-axis), if you want the object to appear on the axis after the operations, the rotation must occur first, followed by the translation. To do this, the code looks something like this (where R is the rotation matrix and T is the translation matrix):

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMultMatrixf(T);                     /* translation */
glMultMatrixf(R);                     /* rotation */
draw_the_object();

Another way to view matrix multiplications is to forget about a grand, fixed coordinate system in which your model is transformed and instead imagine that a local coordinate system is tied to the object you're drawing. All operations occur relative to this changing coordinate system. With this approach, the matrix multiplications now appear in the natural order in the code. (Regardless of which analogy you're using, the code is the same, but how you think about it differs.) To see this in the translation-rotation example, begin by visualizing the object with a coordinate system tied to it. The translation operation moves the object and its coordinate system down the x-axis. Then, the rotation occurs about the (now-translated) origin, so the object rotates in place in its position on the axis.




Hope that helps.