::[ PART 13 - SCALING / ROTATION / TRANSLATION ]::[ Source ]::[ Printable Version ]::
::[ DISCLAIMER ]::
I will hold no responsibility to whatever happens to you, your computer, your sanity, your pet, or whatever that may happen to your existence for your reading these texts and for the outcome of the various source code(s) given in each tutorial. So in short, read at your own risk!

 
::[ INTRODUCTION ]::
Ahhh, yes, scaling, rotation, and translation...they may sound intimidating and hard for those new into the realm of three dimensional graphics, but hey, remember that we're using OpenGL here...so don't worry!

Anyway, if it's not obvious enough, scaling changes the size of the polygons that are rendered. As for rotation, well, what more can I say, we will learn how to rotate a polygon in this tutorial! Should I bother introducing what translation is? Yes? Oh, ok...it's simply moving your polygons around your three dimensional world...;).

SideNote: You may be surprised as to how easy scaling, rotation, and translation is. If you know some matrix math, then you are allowed by OpenGL to specify your own rotation matrix, but this is generally not encouraged since it would usually slow down your program / demo / game.

 
::[ TUTORIAL ]::
This tutorial won't be quite as long as previous tutorials...I hope!

Hmm...which topic should I start with...scaling or rotation or translation? (Flips a three-sided coin) The coin shows: HEAD! So scaling it is!

SCALING:

The main idea to keep in mind here is that scaling affects the SIZE of whatever it is that you are drawing. Whenever you scale with the OpenGL command that I will introduce later, you will be scaling the current world axis.

The "current world axis" that I am referring to above is your imaginary axis that exists whenever you are working with OpenGL. This is the same imaginary axis that you used (probably unknowingly) in Part 12 where I introduced to you guys how to draw primitives!...;).

OK, enough chit-chat, here's the code:

  //----8<----[ CODE BEGIN ]--------//
    glScalef(0.5f, 2.0f, 1.0f);
  //----8<----[ CODE END   ]--------//

Surprised? Only one line of code? Yes, sorry, as much as I'd want to complicate your life, I can only show you one line of code right now...:(.

Anyway (kidding aside)...

The first parameter accepts the new scaling values for the x-axis, while the second parameter is for the y-axis, and the third, the z-axis.

I placed for my first parameter a 0.5f, the 'f' in 0.5 means it's a float -- not really necessary but it's a good habit to get in to...

Now, this 0.5f will mean that everything that I draw will now get half the value along the x-axis. This is because 0.5f tells OpenGL to "shrink" (or should I say "scale"? :) ) the size of whatever object that you're drawing along the x-axis...

...if you were to, for example, give glScalef() a 3.0f for the first parameter, then you'd be increasing whatever object that you're drawing along the x-axis three-folds!

You see, what we're scaling here is not the vertices, but the current world axis. When we scaled our world with the code above, we told OpenGL to scale our x-axis by 0.5f (or one-half) and the y-axis by 2.0f (or twice) of what it was originally. The z-axis was not scaled since we used 1.0f.

Just imagine it this way: since I gave a 0.5f value for my first parameter above inside glScalef(), then everytime I give OpenGL a vertex (probably through glVertex3f()), OpenGL will multiply a 0.5 to the x-coordinate of the vertex that I passed to it.

The same goes true for the second and third parameters of glScalef()...except now they affect the y and z-coordinates.

Here's an example:

  //----8<----[ CODE BEGIN ]--------//
    glLoadIdentity();                   // Reset Matrix
    glScalef(0.5f, 2.0f, 1.0f);

    glBegin(GL_POINT);
      glColor3ub(255,255,255);          // White Color!
      glVertex3f(1.0f, 2.0f, 3.0f);
    glEnd();
  //----8<----[ CODE END   ]--------//

Here, instead of plotting my (white) vertex at coordinates (1.0, 2.0, 3.0), I will get (0.5, 4.0, 3.0).

Note: If I were to use glScalef(1.0f, 1.0f, 1.0f), then that would mean that I'm not really changing anything to the size of my objects. Interestingly enough, if I were to use glScalef(0.0f, 0.0f, 0.0f), then I would not see anything at all!

Oh yeah, notice my usage of glLoadIdentity() above, you need to reset your matrix. You see, OpenGL has this matrix (this matrix is just a 4x4 array -- so don't worry!) that it modifies whenever you make calls like glScalef(). If you don't place the glLoadIdentity() there, then everytime you call your rendering loop, OpenGL will again shrink the current world axis by 0.5f, and then for the next loop, by 0.5f, and so on until you see nothing...;).

There will be further discussions about matrices (plural for "matrix" hehe) in Part 16 of my tutorials (you're currently in Part 13).

And that, my friends, is scaling.

(Willie flips his three-sided coin again to know whether to discuss rotation or translation next...and Willie gets: HEADS AGAIN! AAAAaarrrghh...useless coin!...)

(And so, Willie throws away his three-sided coin...and the world, with all its majestic glory and wonders, will never see again...a three-sided coin...)

(After 10 hours of pondering life's mysteries as though it had anything to do with Willie's choosing of whether to discuss rotation next or translation, Willie decided to discuss rotation first before translation just because "rotation" comes first in the common English dictionary...).

 
ROTATION:

Now, to be less talkative, I'll show you the code for rotation as early as now:

  //----8<----[ CODE BEGIN ]--------//
    static FLOAT angle = 0.0f;

    glLoadIdentity();                   // Reset Matrix
    glTranslatef(0.0f, 0.0f, -5.0f);    // Translate -5 Z-Units
    glRotatef(angle, 0.0f, 1.0f, 0.0f); // Rotate 1 Deg. Around Y-Axis

    glBegin(GL_TRIANGLES);		  // I Want To Draw A Triangle
      glColor3ub(0,255,0);		  // First Vertex's Color
      glVertex3f(0.0, 1.0, 0.0);	  // First Vertex's Position

      glColor3ub(0,0,255);		  // Second Vertex's Color
      glVertex3f(-1.0, -1.0, 0.0);	  // Second Vertex's Position

      glColor3ub(255,0,0);		  // Third Vertex's Color
      glVertex3f(1.0, -1.0, 0.0);	  // Third Vertex's Position
    glEnd();

    angle = angle + 1.5f;
  //----8<----[ CODE END   ]--------//

You will find in the code above the OpenGL command: glRotatef(). The first parameter accepts how many degrees to rotate the object that you will draw. The next three parameters are the end-vertices of where your object will rotate about, starting from (0.0f, 0.0f, 0.0f).

This means that glRotatef() orders OpenGL to let whatever it is that we want to draw, rotate around the line (0.0f, 0.0f, 0.0f) to (0.0f, 1.0f, 0.0f).

As simple as that!

Oh yeah, note that a line extends both sides infinitely! Note also that I have also included the OpenGL command: glTranslatef() above. which is good since I'm going to discuss translation next...:).

 
TRANSLATION:

OK. When we say that we want an object "translated 3 units to the left", what we mean that we want our object to move to the left 3 units (Duh Willie!).

To accomplish this, we use glTranslatef(). glTranslatef() has three parameters (as introduced in the code along with rotation above). The first parameter "moves" the world by x-units, the second parameter "moves" the world by y-units, and the third, well, "moves" the world by z-units.

So if I were to say glTranslatef(1.0f, 2.0f, -3.0f), I'd be "moving" my world 1-unit to the left, 2-units up, and 3-units further inside of where I am now.

Note that we get different results when we call glTranslatef() first before glRotatef(). Think of it this way:

      A  slave was  asked  by  his  master to  stand at  a certain  position
      in a room...this position was called (drum rolls please) "POSITION A".

      The slave was then asked (for some reason) by his weird master to draw
      the floor with dots. The master orders: "Slave! Move three steps north
      then  call your new  position "POSITION B", and  then turn -90 degrees 
      from "POSITION A", there, you shall draw a dot on the floor!".

      The slave follows and thus, the slave takes  three steps to the north,
      called  his  new position  "POSITION B", and  then  turned -90 degrees
      from "POSITION A". Here is a top-view of how the slave did it:

	        +-------------------------------------+
	        |                                     |
	        |                    (North)          |
	        |                                     |
	        |                   POSITION B        |
	        |                       @             |
	        |                       :             |
	        |                       :             |
	        |                       :             |
	        |                       :             |
	        |                       :             |
	        |                       :             |
	        |   (New Dot)          _:             |
	        |       @.............|.@             |
	        |                   POSITION A        |
	        |                                     |	
	        +-------------------------------------+

      The master then says: "Slave! Go back to where you were originally!".
      And  so  the  slave went  back to "POSITION A"  and  stood  where  he 
      originally stood. 

      The  master  then  orders: "Slave! Turn -90 degrees from "POSITION A"  
      and  move three units  north and plot a dot on the floor!". The slave 
      follows  and  turns -90  degrees (turns  left)  then took three steps 
      north  and  plots a dot". Here is  a top-view illustration of how the 
      slave did this order:

	        +-------------------------------------+
	        |                                     |
	        |                    (North)          |
	        |                                     |
	        |                   POSITION B        |
	        |                     (Dot)           |
	        |                       @             |
	        |                       :             |
	        |                       :             |
	        |                       :             |
	        |                       :             |
	        |                       :             |
	        |                       :             |
	        | (Dot from 1st Order)  :             |
	        |       @               @             |
	        |                   POSITION A        |
	        |                                     |
	        +-------------------------------------+

      The master then gave his slave his freedom for following him so well.
Now, the moral of the story is...err, wait, no, that's not what I'm supposed to explain...

What I wanted to say (and point out) is that the slave was able to draw two dots. This may seem obvious from my story but it might surprise you guys how many people have trouble imagining what will happen if you glTranslatef() first before you glRotatef() (and vice-versa) in OpenGL.

Oh yeah, in my "story" above, whenever the slave moved, it is analogous to calling a glTranslatef() in OpenGL, and whenever the slave turned, it is analogous to calling glRotatef(). The slave is OpenGL, and the weird master is you, the programmer (hehehe...=) ). Imagine, and be amazed!...:).

Tadah! We're DONE!!! The source code provided with this tutorial didn't change THAT much...just look at the function Render(), it's the only function that has been modified.

 
::[ ENDING ]::
And that's that! Not hard eh? If there is anything that's not clear to you, your mind, or to that part of you that lets you comprehend the things here, you may email me at:

As you can see, it's really simple to scale and rotate and move your objects in 3D. It's just a matter of getting used to.

(Oh yeah, there's no such thing as a three-sided coin -- at least none that I know of. I used that three-sided coin idea to keep things interesting for you readers -- just in case you were wonderin'...;) ).

Part 14 will be about texturemapping. This will be the first time we load a texture in our program!

Briefly, texturemapping is the art of "pasting" images (aka textures) onto a polygon. This will give the polygon more realism as to what it really is (like a crate, for example). So check out Part 14!

 
::[ REFERENCE ]::
I want to recommend this site to you:

This site has tutorials somewhat like GameTutorials.Com but is still worth a look! It also has tutorials on how to use CgShaders with OpenGL!

 
::[ NOMAD.SOURCE ]::

  gfxOpenGL3.zip - MSVC++ 6.0 source
This tutorial was written on: 11.26.2002 | Updated: 12.11.2002
:.Site.:.Menu.:
:// .site..news.
:// .tutorials..1.
:// .tutorials..2.
:// .projects.
:// .forums.
:// .gbook.
:// .links.