Why does this OpenGL rotation also translate my object? - c++

I'm trying to rotate an object (an arrow) which has it's default position as pointing to the right. I've been looking around and I'm using the glLoadIdentity() and glPushMatrix() and glPopMatrix() as a way to only rotate the object in my glBegin function and not the whole scene:
glLoadIdentity();
glPushMatrix();
glRotatef(5, 0.0f, 0.0f, 1.0f);
glBegin(GL_TRIANGLE_FAN);
glColor3f(1.0f, 0.0f, 1.0f);
glVertex2f(xx2-0.01, yy2);
glVertex2f(xx2-0.06, yy2+0.03);
glVertex2f(xx2-0.06, yy2-0.03);
glEnd();
glPopMatrix();
However, it also translates my arrow, instead of only rotating it. Do I need to translate the offset back to it's original position? Or am I doing something wrong?
SOLVED:
glLoadIdentity();
glPushMatrix();
glTranslatef(xx2, yy2, 0);
glRotatef(45, 0.0f, 0.0f, 1.0f);
glTranslatef(-xx2, -yy2, 0);
glBegin(GL_TRIANGLE_FAN);
glColor3f(1.0f, 0.0f, 1.0f);
glVertex2f(xx2-0.01, yy2);
glVertex2f(xx2-0.06, yy2+0.03);
glVertex2f(xx2-0.06, yy2-0.03);
glEnd();
glPopMatrix();
Need to translate back to center (0, 0, 0), apply the rotation and then back to it's original position (xx2, yy2, 0)

All rotations are around the origin.
So yes, if you want to rotate around some other point, you must translate from that point to the origin, rotate, and then translate back again.

Your code is correct, but you are applying your operations out of order. Specifically, you need to apply the rotation first, then apply the translation.

Related

Adding a Light Source to 3D objects in OpenGL

I was wondering if anyone could help me figure out how to add a light source to my 3D objects. I have four objects that are rotating and I want the light source to be at a fixed position, and I want to be able to see lighting on the object.
I tried doing this (********):
//*******Initializing the light position
GLfloat pos[] = {-2,4,5,1};
void display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
//*******adding the light to the display method
glLoadIdentity();
glLightfv(GL_LIGHT0, GL_POSITION, pos);
// rectangle
glPushMatrix();
glTranslatef(0.0f, 2.5f, -8.0f);
glRotatef(angleRectangle, 0.0f, 1.0f, 0.0f);
drawRectangle();
glPopMatrix();
//small cylinder
glPushMatrix();
glTranslatef(0.0f, 2.0f, -8.0f);
glRotatef(90, 1, 0, 0);
glRotatef(anglePyramid, 0.0f, 0.0f, 1.0f);
drawCylinder(0.2, 0.7);
glPopMatrix();
//big cylinder
glPushMatrix();
glTranslatef(0.0f, 1.5f, -8.0f);
glRotatef(90, 1, 0, 0);
glRotatef(anglePyramid, 0.0f, 0.0f, 1.0f);
drawCylinder(0.7, 2.7);
glPopMatrix();
//pyramid
glPushMatrix();
glTranslatef(0.0f, -2.2f, -8.0f);
glRotatef(180, 1, 0, 0);
glRotatef(anglePyramid, 0.0f, 1.0f, 0.0f);
drawPyramid();
glPopMatrix();
glutSwapBuffers();
anglePyramid += k * 0.2f; //- is CW, + is CCW
angleRectangle += -k * 0.2f;
}
//******* Then i added these to the main method
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
However when I do this and I run the entire program, my objects turn gray, and at certain points in the rotation they turn white. And this isnt what I want. I want to keep my colorful objects, but I want to be able to see the light source on them.
Any help would be greatly appreciated. Also let me know if you need to see more of my code to figure out the issue. Thanks
When lighting (GL_LIGHTING) is enabled, then the color is taken from the material parameters (glMaterial).
If you still want to use the current color, the you have to enable GL_COLOR_MATERIAL
and to set the color material paramters (glColorMaterial):
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
See also Basic OpenGL Lighting.
But note, that drawing by glBegin/glEnd sequences, the fixed function pipeline matrix stack and fixed function pipeline per vertex light model, is deprecated since decades.
Read about Fixed Function Pipeline and see Vertex Specification and Shader for a state of the art way of rendering.

Rotating an object around a fixed point in opengl

I have a problem with this openGL code:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix(); // put current matrix on stack
//glTranslatef(0.0f, 0.0f, 0.0f);
//glTranslatef(-4*1.5, 0.0, 4*1.5);
glRotatef(rotationAngle, 0.0f, 1.0f, 0.0f); // rotate the robot on its y-axis
glTranslatef(xpos, ypos, zpos);
DrawRobot(xpos, ypos, zpos); // draw the robot
glPopMatrix();
What should I do to make my robot turn around the point at which it is currently situated and not around the origin? I think the problem lies in this snippet.
Example of rotating an object around its centre along the z-axis:
glPushMatrix();
glTranslatef(250,250,0.0); // 3. Translate to the object's position.
glRotatef(angle,0.0,0.0,1.0); // 2. Rotate the object.
glTranslatef(-250,-250,0.0); // 1. Translate to the origin.
// Draw the object
glPopMatrix();
Simply do the rotation after the translation. The order matters.
glTranslatef(xpos, ypos, zpos);
glRotatef(rotationAngle, 0.0f, 1.0f, 0.0f);
try rotating after translation:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix(); // put current matrix on stack
//glTranslatef(0.0f, 0.0f, 0.0f);
//glTranslatef(-4*1.5, 0.0, 4*1.5);
glTranslatef(xpos, ypos, zpos);
glRotatef(rotationAngle, 0.0f, 1.0f, 0.0f); // rotate the robot on its y-axis
DrawRobot(xpos, ypos, zpos); // draw the robot
glPopMatrix();
Use this
house();
glTranslatef(x, y, 0.0); // 3. Translate back to original
glRotatef(theta, 0.0, 0.0, 1.0); // 2. Rotate the object around angle
glTranslatef(-m, -n, 0.0); // 1. Move to origin
house();
where m and n are the point on the object around which you want to rotate and
x and y are the points around which you want to rotate.

opengl rotate an object to set its correct face before render on screen

I am loading an object through an obj file in opengl using GLM Library but it comes out on the screen upside down. Also i am providing a capability to user so he can rotate all the objects accordingly by mouse too. e.g. zoom and zoom in and rotate with y axis.
Problem is i dont know how to rotate the object first to make its face according to what i need. After that i want to draw this object and offcourse at that time mouse can play its role to rotate it.
my draw function contain the following code
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glTranslatef(m_fPosX, m_fPosY,-m_fZoom);
glRotatef(m_fRotX, 1.0f, 0.0f, 0.0f);//these two for mouse movement
glRotatef(m_fRotY, 0.0f, 1.0f, 0.0f);
glRotated(180,0.0f, 0.0f, -1.0f);
glDisable(GL_TEXTURE_2D);
glColor3f(0.90f,0.90f,0.90f);
glmDraw(m_p3dModel,GLM_SMOOTH | GLM_MATERIAL);
glPopMatrix();
here rotate functions are all dependent on mouse movement but if it get load upside down i dont know how to first make my object face right direction and then allow it in this draw function...Which means i need to set its face before calling this draw function.
glRotatef(m_fRotY, 1.0f, 0.0f, 0.0f);
should be
glRotatef(m_fRotY, 0.0f, 1.0f, 0.0f);
copy/paste is the mother of many evils :o)
For transformation / projection / model view tutorial : check link

Using glLoadMatrixf with my own matrix

I have a simple drawing loop where I manipulate the camera, using glRotatef and glTranslatef then I attempt to draw a an object with my own matrix instead of using the gl* commands
e.g.
void GLCore::render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef(camera.xRot,1.0,0.0,0.0);
glRotatef(camera.yRot,0.0,1.0,0.0);
glTranslatef(-camera.position.X, -camera.position.Y, -camera.position.Z);
glPushMatrix();
drawScene();
glPopMatrix();
camera.updateCamera();
}
void GLCore::drawScene()
{
glEnableClientState(GL_VERTEX_ARRAY);
glPushMatrix();
glLoadMatrixf(mapObject->matrix.getMatrixPointer());
glVertexPointer(....);
glDrawElements(....);
glPopMatrix();
glDisableClientState(GL_VERTEX_ARRAY);
}
The Matrix is from mapObject as:
float m[] = { 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, -10.0f, 1.0f };
This draws as expect, with the model 10.0f away, however when I use glLoadMatrix I loose control of the camera, the view is fixed in the initial state. This doesn't happen when I move the object using glTranslate, everything works fine and the camera will still look around. From what I understand the glLoadMatrix call should only be applied to the top matrix in the stack so it shouldn't effect the camera matrix.
Any ideas? :(
Thanks for the help
glLoadMatrix assigns your matrix to the top of the stack. What you want to do is to multiply your matrix with the one on the top of the stack. Use glMultMatrix for that.

How to rotate model not camera in OpenGL?

I have the same qustion as in the title :/
I make something like:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0, -zoom);
glRotatef(yr*20+moveYr*20, 0.0f, 1.0f, 0.0f);
glRotatef(zr*20+moveZr*20, 1.0f, 0.0f, 0.0f);
//Here model render :/
And in my app camera is rotating not model :/
Presumably the reason you believe it's your camera moving and not your model is because all the objects in the scene are moving together?
After rendering your model and before rendering other objects, are you resetting the MODELVIEW matrix? In other words, are you doing another glLoadIdentity() or glPopMatrix() after you render the model you're talking about and before rendering other objects?
Because if not, whatever transformations you applied to that model will also apply to other objects rendered, and it will be as if you rotated the whole world (or the camera).
I think there may be another problem with your code though:
glTranslatef(0.0f, 0, -zoom);
glRotatef(yr*20+moveYr*20, 0.0f, 1.0f, 0.0f);
glRotatef(zr*20+moveZr*20, 1.0f, 0.0f, 0.0f);
//Here model render :/
Are you trying to rotate your model around the point (0, 0, -zoom)?
Normally, in order to rotate around a certain point (x,y,z), you do:
Translate (x,y,z) to the origin (0,0,0) by translating by the vector (-x,-y,-z)
Perform rotations
Translate the origin back to (x,y,z) by translating by the vector (x,y,z)
Draw
If you are trying to rotate around the point (0,0,zoom), you are missing step 3.
So try adding this before you render your model:
glTranslatef(0.0f, 0, zoom); // translate back from origin
On the other hand if you are trying to rotate the model around the origin (0,0,0), and also move it along the z-axis, then you will want your translation to come after your rotation, as #nonVirtual said.
And don't forget to reset the MODELVIEW matrix before you draw other objects. So the whole sequence would be something like:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
#if you want to rotate around (0, 0, -zoom):
glTranslatef(0.0f, 0, -zoom);
glRotatef(yr*20+moveYr*20, 0.0f, 1.0f, 0.0f);
glRotatef(zr*20+moveZr*20, 1.0f, 0.0f, 0.0f);
glTranslatef(0.0f, 0, zoom); // translate back from origin
#else if you want to rotate around (0, 0, 0):
glRotatef(yr*20+moveYr*20, 0.0f, 1.0f, 0.0f);
glRotatef(zr*20+moveZr*20, 1.0f, 0.0f, 0.0f);
glTranslatef(0.0f, 0, -zoom);
#endif
//Here model render :/
glLoadIdentity();
// translate/rotate for other objects if necessary
// draw other objects
You use GL_MODELVIEW when defining the transformation for your objects and GL_PROJECTION to transform your viewpoint.
I believe it has to do with the order in which you are applying your transformations. Try switching the order of the call to glRotate and glTranslate. As it is now you are moving it outward from the origin, then rotating it about the origin, which will give the appearance of the object orbiting around the camera. If you instead rotate it while it is still at the origin, then move it, it should give you the desired result. Hope that helps.