Jump to content

  • Log In with Google      Sign In   
  • Create Account

glRotate - How does it really work?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
11 replies to this topic

#1 OneMoreToGo   Members   -  Reputation: 124

Like
0Likes
Like

Posted 09 July 2006 - 09:16 AM

When using glRotate, for example this:
glRotatef(34.0, 0.0, 0.0, 0.0);
And then drawing using gl's built in rect command, the rectangle rotates the way I want it to. But if I draw something using glVertex commands, it seems mis-aligned. Negative rotations move the object to the right, positive to the left, and not just in a rotational sense. They actually seem to move their x and y values. I've read the man page for glRotate, but it has not helped to clarify my understanding of this issue. Perhaps one of you could explain to me what glRotate really does? And why or how I'm not using it correctly. Also, if I wanted to rotate the result of a glDrawPixels command, would I use glRotate or something else? Thanks!

Sponsor:

#2 Kalasjniekof   Members   -  Reputation: 246

Like
0Likes
Like

Posted 09 July 2006 - 09:26 AM

Quote:
Original post by OneMoreToGo
But if I draw something using glVertex commands, it seems mis-aligned. Negative rotations move the object to the right, positive to the left, and not just in a rotational sense. They actually seem to move their x and y values.
Please post your rendering code, you might be doing something wrong.

Quote:

Also, if I wanted to rotate the result of a glDrawPixels command, would I use glRotate or something else?

Thanks!
glDrawPixels() isn't affected by transformations. Use textures on primitives instead.



#3 Pipo DeClown   Members   -  Reputation: 804

Like
0Likes
Like

Posted 09 July 2006 - 09:33 AM

glRotatef() works with radians. 2pi radians = 360 degrees.
The 3 floats represent the axis in which to turn. (0, 1, 0) points up 'î', so it turns around the up-pointing axis. (1, 0, 0) points ->, so it turns around the X-axis.
I'm not back. I'm just visiting.

#4 darookie   Members   -  Reputation: 1437

Like
0Likes
Like

Posted 09 July 2006 - 09:48 AM

Quote:
Original post by Pipo DeClown
glRotatef() works with radians. 2pi radians = 360 degrees.

No. The rotation angle is in degrees - unless the Bluebook lies [smile].




#5 Brother Bob   Moderators   -  Reputation: 8632

Like
0Likes
Like

Posted 09 July 2006 - 09:49 AM

Quote:
Original post by Pipo DeClown
glRotatef() works with radians. 2pi radians = 360 degrees.

No, it uses degrees.


#6 OneMoreToGo   Members   -  Reputation: 124

Like
0Likes
Like

Posted 09 July 2006 - 10:01 AM

Quote:
Original post by Kalasjniekof
glDrawPixels() isn't affected by transformations. Use textures on primitives instead.


Darn...

The source in question is part of the newer version of my glSurface, here it is:


#include <cstdlib>

#include "OpenGL/gl.h"
#include "OpenGL/glu.h"

#include "IL/il.h"
#include "IL/ilu.h"
#include "IL/ilut.h"

using namespace std;

class glSurface {

protected:
GLint components;
GLsizei width;
GLsizei height;
GLenum format;
GLvoid *pixels;

ILuint image_IL;
GLuint texture_GL;

int x;
int y;
float rot;

public:
glSurface();
int Open(char *);
void Position(int, int);
void Rotate(float);
void Draw();


};

glSurface::glSurface() {
ilGenImages(1, ?_IL);
glGenTextures(1, &texture_GL);
rot = 0.0;
}

int glSurface::Open(char filename[]) {

ILint open_currentBound_IL = ilGetInteger(IL_CUR_IMAGE);
ILboolean open_success_IL;

ilBindImage(image_IL);
open_success_IL = ilLoadImage(filename);
if (open_success_IL == IL_FALSE) {
ilBindImage(open_currentBound_IL);
cout << "Problem!" << endl;
return(-1);
}
components = ilGetInteger(IL_IMAGE_BPP);
width = ilGetInteger(IL_IMAGE_WIDTH);
height = ilGetInteger(IL_IMAGE_HEIGHT);
format = ilGetInteger(IL_IMAGE_FORMAT);
pixels = ilGetData();

ilBindImage(open_currentBound_IL);

glBindTexture(GL_TEXTURE_2D, texture_GL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, components, width, height, 0, format, GL_UNSIGNED_BYTE, pixels);

return(0);
}

void glSurface::Position(int tx, int ty) {
x = tx;
y = ty;
}

void glSurface::Rotate(float amount) {
rot = rot + amount;
}

void glSurface::Draw() {
glBindTexture(GL_TEXTURE_2D, texture_GL);

glRotatef(rot, 0.0, 0.0, 1.0);

glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex2i(x, y);
glTexCoord2i(0, 1); glVertex2i(x + width, y);
glTexCoord2i(1, 1); glVertex2i(x + width, y + height);
glTexCoord2i(1, 0); glVertex2i(x, y + width);
glEnd();
}




#7 Pipo DeClown   Members   -  Reputation: 804

Like
0Likes
Like

Posted 09 July 2006 - 10:27 AM

Quote:
Original post by Pipo DeClown
glRotatef() works with radians. 2pi radians = 360 degrees.

It works with degrees, idiot! [grin]

#8 Deception666   Members   -  Reputation: 182

Like
0Likes
Like

Posted 09 July 2006 - 10:38 AM

Quote:
Original post by OneMoreToGo
But if I draw something using glVertex commands, it seems mis-aligned. Negative rotations move the object to the right, positive to the left, and not just in a rotational sense. They actually seem to move their x and y values.
Thanks!


It sounds like you want to rotate the object at a physical location around that objects coordinate frame. When you use the glRotate command, you are multiplying the current matrix stack by the rotation you have specified. When you apply the vertex commands, you are then applying the vertices in this new coordinate frame.

Lets take your example. It looks like you are trying to construct a box at some location (x, y) with a specified width and height. I'm assuming that you have your origin at (0, 0). When you issue the rotate command, you are rotating your origin a specified number of degrees. Lets assume 45 degrees. Your origin is still located at (0, 0) but is now rotated 45 degrees. Any vertex commands issued now will rotate 45 degrees around the orgin point. This might be why you are thinking that it is moving thier (x, y) location.

Negative vs. positive rotations has to deal with how OpenGL represents it coordinate system. OpenGL uses a right handed coordinate system. Positive rotations are CCW and negative rotations are CW.

Try doing this instead.

glRotate(rot, 0, 0, 1);
glTranslate(x, y);
glBegin(...);
glTex(...); glVertex(0,0);
glTex(...); glVertex(width,0);
glTex(...); glVertex(width, height);
glTex(...); glVertex(0, height);
glEnd(...);

#9 swordfish   Members   -  Reputation: 276

Like
0Likes
Like

Posted 09 July 2006 - 10:47 AM

In your original code post, glRotatef(34.0, 0.0, 0.0, 0.0), you are using an invalid axis of 0,0,0, which will likely cause undesired functionality. You will need to provide an angle (degrees) and a unit-vector axis to use glRotate*: glRotatef(angle, axisX,axisY,axisZ)

For example, if you want to rotate around the UP direction (yaw rotate), then you'd use an axis of 0,1,0 (aka Unit-Y): glRotatef(34.0, 0.0,1.0,0.0). For a rotation around the RIGHT direction (pitch rotate), a Unit-X axis is used, and for the AT/FORWARD direction (bank rotate), a Unit-Z axis is used.

From your second code post, I'm pretty sure you'll want to encapsulate your matrix changes (glRotate,etc.) within a glPushMatrix()/glPopMatrix() combo. Also take note that glRotate* rotates about the current origin, which is set using glTranslate*(x,y[,z]) (default is 0,0[,0]).

[edit]
If you want to know how glRotate* really works, then it is nothing more than a little research into matrix math. OpenGL has 3 matrix stacks, ModelView, Projection, and Texture. Usually you will be operating on the ModelView matrix stack. An OpenGL matrix is a 4x4 (4 columns, 4 rows) block of numbers representing the current rotation (x,y,z axes of at/up/right) and translation (x,y,z location). The default matrix is called an 'identity matrix', and represents an unaltered rotation (at: Z=1, up: Y=1) and location (0,0,0). A call to glPushMatrix() will 'push' a new identity matrix onto the top of the stack, thus representing a new rotation/location. Any subsequent geometry calls will be affected by the top-most matrix. Any calls to glRotate/glTranslate will affect the top-most matrix. A call to glPopMatrix() will remove the top-most matrix from the stack. glRotate* is really a convenience method provided by OpenGL to eliminate the need for troublesome matrix math. What it does is generate a 3x3 matrix (rotation, no translation) from your axis/angle values, and multiplies the top-most matrix by the rotation matrix (i.e., matrix math). Likewise, glTranslate generates a 1x1 matrix and adds it to the top-most matrix.

[Edited by - swordfish on July 9, 2006 5:47:03 PM]

#10 OneMoreToGo   Members   -  Reputation: 124

Like
0Likes
Like

Posted 09 July 2006 - 12:42 PM

Quote:
Original post by Deception666

glRotate(rot, 0, 0, 1);
glTranslate(x, y);
glBegin(...);
glTex(...); glVertex(0,0);
glTex(...); glVertex(width,0);
glTex(...); glVertex(width, height);
glTex(...); glVertex(0, height);
glEnd(...);


I'm not sure I understand your solution... glTranslate has no effect on glVertex. Or does it? *Dun dun duuhhh* ;)

I'll try it!

EDIT: And like swordfish said, wouldn't the rotate call have to be AFTER the translate call? :???:

EDIT 2: Tried it, I *think* it worked, but it's hard to tell because the texture has gotten 2 times as big as before!

#11 Deception666   Members   -  Reputation: 182

Like
0Likes
Like

Posted 09 July 2006 - 01:16 PM

Quote:
Original post by OneMoreToGo
I'm not sure I understand your solution... glTranslate has no effect on glVertex. Or does it? *Dun dun duuhhh* ;)


Translating does have an effect on vertices that are passed in to the pipeline. Consider translating from the origin (0, 0, 0) to (10, 0, 0). To do this you would issue a glTranslatef(10.0f, 0.0f, 0.0f). Your origin now is located at (10, 0, 0), so if we issue a glVertex3f(5.0f, 0.0f, 0.0f), we would be multiplying the modelview matrix, which has an origin (10, 0, 0), by the column matrix (5, 0, 0) to obtain a vertex location of (15, 0, 0). There is a bit more to this matrix and vector math, but to answer your question, a translation does effect the final location of a vertex when passed through the pipeline.

Quote:
Original post by OneMoreToGo
EDIT: And like swordfish said, wouldn't the rotate call have to be AFTER the translate call? :???:


No. OpenGL uses post-multiplication for matrix math. Matrices are stored in column major order and represents vertices a column vectors. Because it is post-multiplied, the math is from right to left and not left to right. Left to right would be used by row major order matrices.

Looking at the commands.
We currently have matrix O on the matrix stack. What we want is O` = O * R * T * v. When you issue a translate or rotate command, the current matrix O is replaced by O * C. Looking at the example, issuing a rotate command produces the current matrix: R` = O * R. R` is now the new matrix on the stack. Now issue a translation command to produce the matrix: T` = R` * T. If we replace R` with O * R we get the final result: O * R * T = O`.

Quote:
Original post by OneMoreToGo
EDIT 2: Tried it, I *think* it worked, but it's hard to tell because the texture has gotten 2 times as big as before!


Not quite sure because I would have to look closer at your code. Hope this helps you.



#12 OneMoreToGo   Members   -  Reputation: 124

Like
0Likes
Like

Posted 10 July 2006 - 08:34 AM

Thanks, kalas! (Perhaps without realizing it), you have reinforced my weak understanding of matrices!




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS