OpenGL OpenGL Rotation Origin Problems

Recommended Posts

Hi guys, I've had a browse around and can't seem to find any mention of this, i'm starting to make progress with learning OpenGL, but theres one thing thats totally throwing me off for the time being. Maybe someone will be kind enough to shed some light on this for me. Currently, i am simply rendering a textured rectangle to the screen. I was thumbing through tutorials and wanted to improve my rendering by adding in some rotation and possibly throw in some alpha blending when i came across this post http://www.iphonedevsdk.com/forum/iphone-sdk-development/2060-how-extend-texture2d-opacity.html Huzzah i thought, as i happily modded my blitting method to include rotations and was presented with a slightly rotated object, but all was not as expected. For some reason (which i'm sure is totally obvious), the rectangle is rotated about the top left point, ie: 0.0, 0.0 which is really what i would expect, 0.0, 0.0 being the origin and all... but i want my object to be rotated around its center point, not the origin of the screen. I have set up my glOrthof and glViewport for landscape orientation as such:
glViewport(0.0, 0.0, backingWidth, backingHeight);

//other stuff here

glOrthof(0.0, backingHeight, backingWidth, 0.0, -1.0, 1.0);

This gives me a landscape orientation with the top left coords being 0.0, 0.0 and bottom right being 480.0, 320.0 which is my prefered coordinate system. As of such, this appears to be the main origin for all object rotations, which isn't really what i want. Is there any way i can translate an objects origin to rotate around its center point? for example, if i were to render the rect:
my_rect = CGRectMake(backingWidth / 4, backingHeight / 4, backingWidth / 2, backingHeight / 2);

a small rect half the width and height of the device would be presented directly in the center of the screen. Any rotations made to this however would be about the origin of 0.0, 0.0 of the screen and not the object itself. Is there any way to fix this so that the object would rotate around its center piont, in this example being the center of the screen? I dont mind changing the coordinate system if needs be, but i would still prefer to use the current 0.0, 0.0, 480.0, 320.0 landscape orientation as opposed to -1.0, 1.0, 1.0, -1.0 unless of course it would be a feasible endeavour to write a utility function to convert between the two coordinate systems when rendering? It seems that rotations must be made around the origin of the screen/device (0.0, 0.0) but surely that can't be the case as not every object/model rendered is required to rotate around the origin, but rather its own origin, if that makes sense? Is there a way to set the rotation origin, or translate the object to the screen origin, rotate and back again? Using the coordinate system 0.0, 0.0, 480.0, 320.0 for landscape orientation works perfectly, but obviously this issue with rotating objects around the origin is completely holding up any progress i can make. Please, if anyone knows of a method, or any tutorials that can outline what must be done, i would be very grateful for any help you guys can throw my way :) Just for completeness, the code i'm using for rotation is:
glRotate(rotation, 0.0, 0.0, 1.0);

Simple as it may seem, that one single line has caused me a weekend of headaches and very little progress. I'm positive there must be a way to fix this, can anyone point me in the right direction please? Any help would be greatly appreciated, thanks for reading

Share on other sites
May I suggest you pass the origin as a parameter to your blitting function, that way you won't allways be limited to having the origin at the center. All you would need to do then is subtract the origin position from the sprites position. Heres my simple sprite drawing function which is working perfectly fine for my current project.

/////////////////////////////////////////////////////////////////////////////////////////// DrawSprite()/////////////////////////////////////////////////////////////////////////////////////////void DrawSprite(Texture texture, Vector2 position, Rect source, Colour tint, Vector2 origin, float angle){	glPushMatrix();	glLoadIdentity();	glTranslatef(position.X, position.Y, 0.0f);	glRotatef(angle, 0.0f, 0.0f, 1.0f);	glBindTexture(GL_TEXTURE_2D, texture.TextureID());	glBegin(GL_QUADS);	glColor3f(tint.r, tint.g, tint.b);	glTexCoord2f((float)source.X / texture.Width(), (float)source.Y / texture.Height());	glVertex2f(-origin.X, -origin.Y);	glTexCoord2f((float)(source.X+source.Width)/texture.Width(), (float)source.Y/texture.Height());	glVertex2f(-origin.X+(float)source.Width, -origin.Y);	glTexCoord2f((float)(source.X+source.Width)/texture.Width(), (float)(source.Y+source.Height)/texture.Height());	glVertex2f(-origin.X+(float)source.Width, -origin.Y+(float)source.Height);	glTexCoord2f((float)source.X / texture.Width(), (float)(source.Y+source.Height)/texture.Height());	glVertex2f(-origin.X, -origin.Y+(float)source.Height);	glEnd();	glBindTexture(GL_TEXTURE_2D, NULL);	glPopMatrix();}

[Edited by - cNoob on September 16, 2008 5:06:17 PM]

Share on other sites

I've modified my rendering function to include the call to glTranslatef(), but this hasn't yielded the results i was expecting :(

It seems that my texture is still being rotated incorrectly around the top left origin of the rect i am passing to my rendering function. I've pasted the function below for reference:

//draw texture in rect with rotation- (void)drawInRect:(CGRect)rect withOrigin:(CGPoint)origin withRotation:(GLfloat)rotation{	//calculate texture coordinates	GLfloat coordinates[] = {0.0, textureMaxT,							textureMaxS, textureMaxT,							0.0, 0.0,							textureMaxS, 0.0};		//calculate texture vertices	GLfloat vertices[] = {rect.origin.x, rect.origin.y, 0.0,							rect.origin.x + rect.size.width, rect.origin.y, 0.0,							rect.origin.x, rect.origin.y + rect.size.height, 0.0,							rect.origin.x + rect.size.width, rect.origin.y + rect.size.height, 0.0,};	//push the matrix onto the stack	glPushMatrix();		//load identity	glLoadIdentity();		//translate the verticies	glTranslatef(rect.origin.x - origin.x, rect.origin.y -  origin.y, 0.0);		//rotate texture around the z axis	glRotatef(rotation, 0.0, 0.0, 1.0);		//bind the texture to the target	glBindTexture(GL_TEXTURE_2D, textureName);		//set the texture verticies	glVertexPointer(3, GL_FLOAT, 0, vertices);		//set the texture coordinates	glTexCoordPointer(2, GL_FLOAT, 0, coordinates);		//render primitive from texture data	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);		//pop the matrix off of the stack	glPopMatrix();}

My projection is set to use the coordinate system (0.0, 0.0, 480.0, 320.0) where (0.0, 0.0) is the top left of the screen and (480.0, 320.0) is the bottom right.

When calling the function, i am passing a rect which matches the screen dimensions (as above), a 2D point and a rotation value as such:

[MyImageManager drawImage:myImage inRect:CGRectMake(0.0, 0.0, 480.0, 320.0) withOrigin:CGPointMake(240.0, 160.0) withRotation:10.0];

What i currently see on screen in only 1/4 of my rect/texture with the other 3/4's rendered off the top left hand corners of the screen (if that makes sense?) but it also seems that the rotation is still taking place around the top left origin (0.0, 0.0) of the rect itself, rather than the coords i passed through the origin variable.

Perhaps i should be modifying my vertices array to include the origin values? I'm currently drawing blanks on this one, perhaps you can advise?

if i can figure out the syntax for this forum, i will try to post a screen shot to further illustrate my problem.

Share on other sites
Woops, thats what I get for having two solutions with the same name (different locations ><), I've fixed the old code block in the previous post with the correct version.

// Also, you can post an image using the <b>img</b> html tag:<img src="http://link.to.image/screenshot.png">// and you can post code in a neat block using: (without spaces)[ source ]code goes here[ /source ]

:)

Share on other sites
Hi cNoob,

Thanks again for your reply. I'm not at my mac right now (currently at work) but ill be sure to modify my rendering function when i return home.

Your method looks very similar to the previous one your posted (before editing), although your call to glTranslatef() doesn't take into account the position of the texture but i assume this is canceled out by the changes made when constructing your vertices? (using glVertex2f()) ?

I found a post on another forum which said:

1. translate the point of rotation so that it sits at the origin
2. rotate
3. translate back

and the code would look something like this

void rotate2D(float angle, float pointOfRotationX, float pointOfRotationY)
{
// Note that the steps here are in the reverse order of that mentioned above!!
// That's because openGL transformations post-multiply the matrices.
glTranslatef(pointOfRotationX, pointOfRotationY, 0.0f);
glRotatef(angle, 0.0f, 0.0f, 1.0f);
glTranslatef(-pointOfRotationX, -pointOfRotationY, 0.0f);
}

I think i may be styarting to understand the cause of the problem a lot more now, which should hopefully help me identify the solution but i may have to brush up on my knowledge of matrices (its been a few years since i used OpenGL and even then i only scratched the surface).

Thanks for your help and your code snippet, it really is appreciated, ill be sure to post again if i run into any further problems :)

Create an account

Register a new account

• Partner Spotlight

• Forum Statistics

• Total Topics
627655
• Total Posts
2978460
• Similar Content

• Both functions are available since 3.0, and I'm currently using glMapBuffer(), which works fine.
But, I was wondering if anyone has experienced advantage in using glMapBufferRange(), which allows to specify the range of the mapped buffer. Could this be only a safety measure or does it improve performance?
Note: I'm not asking about glBufferSubData()/glBufferData. Those two are irrelevant in this case.
• By xhcao
Before using void glBindImageTexture(    GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format), does need to make sure that texture is completeness.
• By cebugdev
hi guys,
are there any books, link online or any other resources that discusses on how to build special effects such as magic, lightning, etc. in OpenGL? i mean, yeah most of them are using particles but im looking for resources specifically on how to manipulate the particles to look like an effect that can be use for games,. i did fire particle before, and I want to learn how to do the other 'magic' as well.
Like are there one book or link(cant find in google) that atleast featured how to make different particle effects in OpenGL (or DirectX)? If there is no one stop shop for it, maybe ill just look for some tips on how to make a particle engine that is flexible enough to enable me to design different effects/magic
let me know if you guys have recommendations.
• By dud3
How do we rotate the camera around x axis 360 degrees, without having the strange effect as in my video below?
Mine behaves exactly the same way spherical coordinates would, I'm using euler angles.
Tried googling, but couldn't find a proper answer, guessing I don't know what exactly to google for, googled 'rotate 360 around x axis', got no proper answers.

References:
Code: https://pastebin.com/Hcshj3FQ
The video shows the difference between blender and my rotation:

• By Defend
I've had a Google around for this but haven't yet found some solid advice. There is a lot of "it depends", but I'm not sure on what.
My question is what's a good rule of thumb to follow when it comes to creating/using VBOs & VAOs? As in, when should I use multiple or when should I not? My understanding so far is that if I need a new VBO, then I need a new VAO. So when it comes to rendering multiple objects I can either:
* make lots of VAO/VBO pairs and flip through them to render different objects, or
* make one big VBO and jump around its memory to render different objects.
I also understand that if I need to render objects with different vertex attributes, then a new VAO is necessary in this case.
If that "it depends" really is quite variable, what's best for a beginner with OpenGL, assuming that better approaches can be learnt later with better understanding?

• 10
• 12
• 22
• 13
• 33