OpenGL Rotatef

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

User avatar
ibly31
Chaos Rift Junior
Chaos Rift Junior
Posts: 312
Joined: Thu Feb 19, 2009 8:47 pm
Current Project: Like... seven different ones
Favorite Gaming Platforms: Xbox 360, Gamecube
Programming Language of Choice: C++, ObjC
Location: New Jersey.

OpenGL Rotatef

Post by ibly31 »

For some reason, every time I use glRotatef() in my iphone programs, it rotates the object I want to rotate around in what seems to be a circle... I think it might be rotating the entire viewport, but thats just my guess. Here is my code:

Drawing code:

Code: Select all

- (void)drawView:(GLView*)view;
{
    glClearColor(0.7, 0.7, 0.7, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
    glLoadIdentity();
	CGPoint point = CGPointMake(100.0, 100.0);
	[texture drawAtPoint:point rot: rotat];
	rotat++;

}
Texture2D's modified drawing code:

Code: Select all

- (void) drawAtPoint:(CGPoint)point rot:(GLfloat)rota
{
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	
	GLfloat		coordinates[] = { 0,	_maxT,
								_maxS,	_maxT,
								0,		0,
								_maxS,	0 };
	GLfloat		width = (GLfloat)_width * _maxS,
				height = (GLfloat)_height * _maxT;
	GLfloat		vertices[] = {	-width / 2 + point.x,	-height / 2 + point.y,	-1.0,
								width / 2 + point.x,	-height / 2 + point.y,	-1.0,
								-width / 2 + point.x,	height / 2 + point.y,	-1.0,
								width / 2 + point.x,	height / 2 + point.y,	-1.0 };
	glLoadIdentity();
	glRotatef(rota, 0.0, 0.0, 1.0);
	glBindTexture(GL_TEXTURE_2D, _name);
	glVertexPointer(3, GL_FLOAT, 0, vertices);
	glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
	
	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
I don't know what is wrong. It seems that every time I start a GL project, everything works up until I try to do texture mapping, then rotation is weird.


Any help?

EDIT: All the other tutorials involving rotation that Ive seen, the object is at 0.0,0.0,0.0 maybe glRotatef rotates the entire 3D world? Is there a way to just rotate one object?
Image
Twitter
Website/Tumblr
My Projects

The best thing about UDP jokes is that I don’t care if you get them or not.
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: OpenGL Rotatef

Post by Falco Girgis »

You need to rotate after you've translated your object rather than before.

Code: Select all

   glVertexPointer(3, GL_FLOAT, 0, vertices);
   glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
I am not sure if VertexPointer actually translates around the vertices or not, but the rotation should be applied after this.
User avatar
Innerscope
Chaos Rift Junior
Chaos Rift Junior
Posts: 200
Joined: Mon May 04, 2009 5:15 pm
Current Project: Gridbug
Favorite Gaming Platforms: NES, SNES
Programming Language of Choice: Obj-C, C++
Location: Emeryville, CA
Contact:

Re: OpenGL Rotatef

Post by Innerscope »

Code: Select all

   glRotatef(rota, 0.0, 0.0, 1.0);
This rotates the scene around the origin.
To rotate an object do something like:

Code: Select all

glPushMatrix();
glRotatef(angle,x,y,z);
//Draw object
glPopMatrix();
This saves the previous view transformation, transforms the view, then restores it.

[Edit] Also glLoadIdentity() resets the modelview matrix, you should only call this once per render. (for what you're trying to accomplish)

Side note: I keep getting blacklisted :(
Current Project: Gridbug
Website (under construction) : http://www.timcool.me
User avatar
ibly31
Chaos Rift Junior
Chaos Rift Junior
Posts: 312
Joined: Thu Feb 19, 2009 8:47 pm
Current Project: Like... seven different ones
Favorite Gaming Platforms: Xbox 360, Gamecube
Programming Language of Choice: C++, ObjC
Location: New Jersey.

Re: OpenGL Rotatef

Post by ibly31 »

Hmm... I have tried both of these, putting the rotation code after the vertexpointer call and then the rotation after the pushmatrix, draw then popmatrix... neither seem to have worked...
Image
Twitter
Website/Tumblr
My Projects

The best thing about UDP jokes is that I don’t care if you get them or not.
User avatar
Innerscope
Chaos Rift Junior
Chaos Rift Junior
Posts: 200
Joined: Mon May 04, 2009 5:15 pm
Current Project: Gridbug
Favorite Gaming Platforms: NES, SNES
Programming Language of Choice: Obj-C, C++
Location: Emeryville, CA
Contact:

Re: OpenGL Rotatef

Post by Innerscope »

ibly31 wrote:Hmm... I have tried both of these, putting the rotation code after the vertexpointer call and then the rotation after the pushmatrix, draw then popmatrix... neither seem to have worked...
Are you still rotating about the origin?
Current Project: Gridbug
Website (under construction) : http://www.timcool.me
User avatar
imran.hoshimi
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 12
Joined: Mon Dec 01, 2008 4:57 am
Current Project: Nothing. :(
Favorite Gaming Platforms: PC, XBox360, PS2, SNES and almost all of them.
Programming Language of Choice: C/C++
Location: Karachi, Pakistan.
Contact:

Re: OpenGL Rotatef

Post by imran.hoshimi »

Hello,

I was wondering why are you even caring about Z coordinate when you are using the Texture2D class. AS you have tried to change the Texture2D class to suit your own needs I see that you might have made a slight mistake. Take a look...

Code: Select all

- (void) drawAtPoint:(CGPoint)point rot:(GLfloat)rota
{
   glPushMatrix(); 	

   // Rotate around the Z axis by the angle defined for this image	
   glTranslatef(point.x, point.y, 0);	
   glRotatef(-rota, 0.0f, 0.0f, 1.0f);
// if it still doesn't work, try uncommenting this line also. I will explain later why. :)	
//   glTranslatef(-point.x, -point.y, 0);
   glEnableClientState(GL_VERTEX_ARRAY);
   glEnableClientState(GL_TEXTURE_COORD_ARRAY);   
   glEnable(GL_TEXTURE_2D);   
   GLfloat      coordinates[] = { 0,   _maxT,
                        _maxS,   _maxT,
                        0,      0,
                        _maxS,   0 };
   GLfloat      width = (GLfloat)_width * _maxS,
            height = (GLfloat)_height * _maxT;
   GLfloat vertices[] = { 
-width / 2 + point.x, -height / 2 + point.y,
 width / 2 + point.x, -height / 2 + point.y, 
-width / 2 + point.x, height / 2 + point.y, 
 width / 2 + point.x, height / 2 + point.y
};
   glVertexPointer(2, GL_FLOAT, 0, vertices);
   glTexCoordPointer(2, GL_FLOAT, 0, coordinates);

   glBindTexture(GL_TEXTURE_2D, _name);
   glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
   
   glDisable(GL_TEXTURE_2D);
   glDisableClientState(GL_VERTEX_ARRAY);
   glDisableClientState(GL_TEXTURE_COORD_ARRAY);
   
   glPopMatrix();
}
qpHalcy0n
Respected Programmer
Respected Programmer
Posts: 387
Joined: Fri Dec 19, 2008 3:33 pm
Location: Dallas
Contact:

Re: OpenGL Rotatef

Post by qpHalcy0n »

You need to determine the center of the object you're trying to draw in model space. A simple bounding box test will suffice. You also need to save the current model/view matrix before modifying the state, otherwise you wont be able to get the previous matrix back (actually, you CAN...but it's more math than I'm sure you'd care to go into). The way the glScalef, rotatef, translatef and so forth work is by performing a *postmultiplication* on the current matrix state. So, the order of multiplication DOES matter, and it happens in the order that you think it does. This is the opposite of how most other strict math libs deal with it, which is a *premultiplication* where the order of multiplication (concatenation) happens in the reverse of what you think it does. This applies to 2D cases as well.

So the point in the middle of the object's bounding box is also equal to the vector from the origin to it. So the reversed vector takes you to the origin. Your concatenation becomes:

// Make model/view matrix current //
glMatrixMode(GL_MODELVIEW);

// Save matrix state //
glPushMatrix();

// Translate to origin //
glTranslatef(-objCenter.x, -objCenter.y, -objCenter.z);

// Rotate //
glRotatef(rotX, rotY, rotZ);

// Translate back //
glTranslatef(objCenter.x, objCenter.y, objCenter.z);

RenderStuff();

// Restore matrix //
glPopMatrix();

When you start concatenating more complex transforms you need to pay special attention to order.
Even using glDrawArrays or what have you to render from user/hardware buffers will be passed through the current matrix state.
User avatar
ibly31
Chaos Rift Junior
Chaos Rift Junior
Posts: 312
Joined: Thu Feb 19, 2009 8:47 pm
Current Project: Like... seven different ones
Favorite Gaming Platforms: Xbox 360, Gamecube
Programming Language of Choice: C++, ObjC
Location: New Jersey.

Re: OpenGL Rotatef

Post by ibly31 »

Hmm, but if I do your method with multiple objexts, wont everything ve rotates along with the object im rotating?
Image
Twitter
Website/Tumblr
My Projects

The best thing about UDP jokes is that I don’t care if you get them or not.
User avatar
ibly31
Chaos Rift Junior
Chaos Rift Junior
Posts: 312
Joined: Thu Feb 19, 2009 8:47 pm
Current Project: Like... seven different ones
Favorite Gaming Platforms: Xbox 360, Gamecube
Programming Language of Choice: C++, ObjC
Location: New Jersey.

Re: OpenGL Rotatef

Post by ibly31 »

What exactly are GL_MODELVIEW and another one I think its called GL_PROJECTION
Image
Twitter
Website/Tumblr
My Projects

The best thing about UDP jokes is that I don’t care if you get them or not.
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: OpenGL Rotatef

Post by Falco Girgis »

ibly31 wrote:Hmm, but if I do your method with multiple objexts, wont everything ve rotates along with the object im rotating?
No, because he popped the matrix when he was done.
qpHalcy0n
Respected Programmer
Respected Programmer
Posts: 387
Joined: Fri Dec 19, 2008 3:33 pm
Location: Dallas
Contact:

Re: OpenGL Rotatef

Post by qpHalcy0n »

The GL_MODELVIEW matrix is a concatenated model transform and view transform. A model (or world) transform describes objects relationships to each other in a common coordinate frame. After a modelling transformation the objects are said to be in "worldspace". The view transform is a transformation that transforms the scene around the camera such that the camera resides at the origin, objects are said to be in "view space" after this transform. The projection transform (GL_PROJECTION) describes the shape of the camera volume...there are TONS of different types of projections but the two most frequently used are a perspective projection (gives illusion of depth but does not preserve linearity), and orthographic projection (no depth illusion, but preserves linearity). The result of this puts the vertices in "clip space". After a perspective divide (divide by w), the vertices are in NDC (normalized device coordinates, which in OpenGL is a unit cube from 0-1, in DX is a unit cube from -1 to 1). Texturing is performed generally after the perspective divide and there are ...you guessed it...matrices for that. The texture matrix stack (GL_TEXTURE, GL_TEXTURE0-7) just transforms incoming texture coordinates into a 0-1 UV correct space (which for OpenGL it already is).

OpenGL state matrices are on "stacks" which is a LIFO structure. The modelview stack is at least 32 deep, and the projection stack is at least 2 deep. Anytime you're doing operations to a matrix you're doing them to the one that is on the top of the stack. By pushing a matrix down you're making a copy of it, and pushing the COPY on top of the stack. So you're in effect, saving the old matrix. You do your rendering, then you pop the copy off. Thus giving you the old matrix back.
User avatar
ibly31
Chaos Rift Junior
Chaos Rift Junior
Posts: 312
Joined: Thu Feb 19, 2009 8:47 pm
Current Project: Like... seven different ones
Favorite Gaming Platforms: Xbox 360, Gamecube
Programming Language of Choice: C++, ObjC
Location: New Jersey.

Re: OpenGL Rotatef

Post by ibly31 »

I tried a bunch of the things you said to do... this is my code now:

Code: Select all

- (void) drawAtPoint:(CGPoint)point
{
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	
	GLfloat		coordinates[] = { 0,	_maxT,
								_maxS,	_maxT,
								0,		0,
								_maxS,	0 };
	GLfloat		width = (GLfloat)_width * _maxS,
				height = (GLfloat)_height * _maxT;
	GLfloat		vertices[] = {	-width / 2 + point.x,	-height / 2 + point.y,	-1.0,
								width / 2 + point.x,	-height / 2 + point.y,	-1.0,
								-width / 2 + point.x,	height / 2 + point.y,	-1.0,
								width / 2 + point.x,	height / 2 + point.y,	-1.0 };
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glBindTexture(GL_TEXTURE_2D, _name);
	glVertexPointer(3, GL_FLOAT, 0, vertices);
	
	glTranslatef(-point.x, -point.y, 0); // I'm doing 2D so I dont think I need a number for the Z
	glRotatef(_rota, 0.0, 0.0, 1.0);
	glTranslatef(point.x, point.y, 0); // same here?
	
	glTexCoordPointer(2, GL_FLOAT, 0, coordinates);
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
	glPopMatrix();
	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
With the translate sandwhich around the glRotatef, the object spins around the center, off the screen, then never comes back. Without the glTranslatef's it rotates around the center and will do so until you quit.
Image
Twitter
Website/Tumblr
My Projects

The best thing about UDP jokes is that I don’t care if you get them or not.
qpHalcy0n
Respected Programmer
Respected Programmer
Posts: 387
Joined: Fri Dec 19, 2008 3:33 pm
Location: Dallas
Contact:

Re: OpenGL Rotatef

Post by qpHalcy0n »

Sorry, I made a small mistake, I'd forgotten matrices in OpenGL are row major. (its been awhile :P). Which when multiplying 4 component vectors is the same as pre-multiplying a column major matrix Sorry bout that I just thought about that when reading your code there. So: while logically you're saying "translate to origin, rotate, then translate back". The matrix concatenation should read more like "translate back, rotate, translate to origin".

The second issue you have going on there is that yes, indeed you DO need to translate on the z-axis as well. Most likely you're using an orthographic projection to emulate a 2D environment, and clever usage of the viewport can allow you to map world space positions directly to screen space. However, this does not detract from the fact that you are still using an orthographic projection and the vertices are still a 3 dimensional space.

So, your transformation code should look more like the following:

Code: Select all

glMatrixMode(GL_MODELVIEW);
glPushMatrix();

// Desired translation //
glTranslatef(point.x, point.y, 1.0F);

// Desired rotation //
glRotatef(rotangle, rotx, roty, rotz);

// Translate to origin //
glTranslatef(-point.x, -point.y, -1.0F);

DrawStuff();

//  Restore matrix //
glPopMatrix();
User avatar
ibly31
Chaos Rift Junior
Chaos Rift Junior
Posts: 312
Joined: Thu Feb 19, 2009 8:47 pm
Current Project: Like... seven different ones
Favorite Gaming Platforms: Xbox 360, Gamecube
Programming Language of Choice: C++, ObjC
Location: New Jersey.

Re: OpenGL Rotatef

Post by ibly31 »

That did the trick! Thank you so much! Most of your last post made pretty much no sense to me, because of all the terms. I'm pretty new to OpenGL ES (well this is my first experience with it), so I don't really know what any of the terms mean.
Image
Twitter
Website/Tumblr
My Projects

The best thing about UDP jokes is that I don’t care if you get them or not.
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: OpenGL Rotatef

Post by Falco Girgis »

So what in the hell was his call to glVertexPointer() even doing? I guessed that it was maybe doing the equivalent of a pushMatrix on the vertices.
Post Reply