PDA

View Full Version : Problem with glrotate()



Eratosthenes
10-30-2013, 12:40 PM
Hi there,
I am new to openGL programming, and I got a problem, which, despite my extensive search on the Internet and loads of tries, I can't solve yet. It has to do with rotating a simple QUADS around its center. Here is my ReshapeFunc (the actual code is written in Fortran 2003 using the f03gl bindings, but that is irrelevant to the problem; I post the equivalent C++ code here):

...
double w_d,h_d;
w_d=(double)w; h_d=(double)d;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0d, w_d, h_d, 0.0d, 0.0d, -1.0d, 1.0d);
glMatrixMode(GL_MODELVIEW);
...
I am not interested on 3D for now, so the window just shows the x-y plane. Now, the rendering (and IdleFunc) function is as follows:

...
glPushMatrix();
glRotatef(angle, 0., 0., -1.);
glBegin(GL_QUADS);
glColor3f(0.5, 0.0, 1.0); glVertex2f(100., 100.);
glColor3f(1.0, 0.0, 0.0); glVertex2f(100., 300.);
glColor3f(0.0, 1.0, 0.0); glVertex2f(300., 300.);
glColor3f(1.0, 1.0, 0.0); glVertex2f(300., 100.);
glEnd();
glPopMatrix();
...
where angle is updated each time, adding 1.0. Window size is (400,400). The above code works as expected: it sets the (x=0,y=0) point at the top left corner of the window, draws a 200x200 pixels rectangle at the center of the screen, and rotates it counterclockwise around (x=0,y=0). However, what I want is to rotate the rectangle around the center of the window, (x=200,y=200). I would expect that changing the glRotatef command to

glRotatef(angle, 200., 200., -1.);
would do. Unfortunately, it doesn't work (the rectangle seems to rotate around another axis than a vector vertical to the center of the screen). Apparently, I am missing something important here. If the above code wouldn't work as expected with glRotatef(angle, 0., 0., -1.), I would say I set viewing point incorrectly. However, it works perfectly with glRotatef(angle, 0., 0., -1.) but not with glRotatef(angle, 200., 200., -1.).
Note that if I change the code so that (0,0) is the center of the window,
glRotatef(angle, 0., 0., -1.); will indeed work, rotating the rectangle around its center. However, what I want is to permanently place the (x=0,y=0) point at the top left corner of the window (as it is customary in all multimedia SDKs).
Any help will be greatly appreciated.

Cornix
10-30-2013, 01:18 PM
what you want to do is first translate to move the picture to the center, then rotate, then translate back by the same distance (but negative this time) you moved it earlier.

Eratosthenes
10-30-2013, 03:41 PM
what you want to do is first translate to move the picture to the center, then rotate, then translate back by the same distance (but negative this time) you moved it earlier.Yes, I knew that, and I actually used it already as a workaround, so that the rendering part changes to:
...
glPushMatrix();
glTranslatef(200.,200.,0.)
glRotatef(angle, 0., 0., -1.);
glTranslatef(-200.,-200.,0.);
glBegin(GL_QUADS);
glColor3f(0.5, 0.0, 1.0); call glVertex2f(100., 100.);
glColor3f(1.0, 0.0, 0.0); call glVertex2f(100., 300.);
glColor3f(0.0, 1.0, 0.0); call glVertex2f(300., 300.);
glColor3f(1.0, 1.0, 0.0); call glVertex2f(300., 100.);
glEnd();
glPopMatrix()
...

What this rendering code does is to actually move the rectangle so that its center is at the top left corner of the window, which is (x=0,y=0), rotate it, then moving it back to its original place, so that its center is at the center of the window, (x=200,y=200). However, this also means I can only use glRotatef(angle, 0., 0., -1.). I don't see why I cannot just rotate the object using glRotatef(angle, 200., 200., -1.) without moving (translating) it at all. If I understand well, glRotatef(angle, 200., 200., -1.) means rotate around a vector starting at the center of my window, (x=200,y=200), and pointing "behind the screen", given my glOrho setting. Since (x=200,y=200) is also the center of my object, this should suffice to rotate it around its center (counterclockwise, given the right-hand rule). I don't see why I must move my object first so that (x=0,y=0) is its center, rotate it, then moving it back to its original position.

GClements
10-30-2013, 06:46 PM
If I understand well, glRotatef(angle, 200., 200., -1.) means rotate around a vector starting at the center of my window, (x=200,y=200)
A vector isn't a line, it's a direction. The axis of rotation always passes through the origin; the last three parameters to glRotate() specify its direction.