Rotating two spheres - c++

I want to rotate two spheres continuously both with a different rotation.
My code currently doesn't seem to get either to rotate.
Here is my code:
void renderScene(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslated(0.0,1.2,-6);
glRotatef(angle,0,1.2,-6);
glutSolidSphere(1,50,50);
glPopMatrix();
glPushMatrix();
glTranslatef(0.0,-1.5,-6);
glRotatef(angle,0,1.5,-6);
glutSolidSphere(0.4,50,50);
glPopMatrix();
angle=+0.1;
glutSwapBuffers();
}
Is there something I haven't added?
I have tried the rotate everywhere, and it only seems to work outside the push and pop matrix, which is not what I want.

angle=+0.1; // assign the value +0.1 to angle
Did you mean:
angle += 0.1; // increment angle by 0.1

glutSolidSphere draws a sphere around the origin: (0,0,0). glRotatef rotates also around an axis that passes through the origin. Now, as you probably should know, rotating a sphere around its center does not change the appearance of the sphere at all.
What you should do is first rotate and then translate. Like this:
glPushMatrix();
glRotatef(angle,0,1.2,-6);
glTranslated(0.0,1.2,-6);
glutSolidSphere(1,50,50);
glPopMatrix();

Related

How to place coordinates > 100.0f in opengl?

When I place coordinates like this:
display(){
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, 360.0f);
drawTeapot();
glutSwapBuffers();
}
The teapot is not visible and I want it visible at 360.0f.
I am using this for init,
init()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, width/height, -1000, 1000);
}
It's not a case placing coordinates > 100.0f. For starters your furstrum is wrong as the zNear value should be > 0. There is no negative region of a viewing frustrum :).
The translation you are doing on the ModelView matrix is the wrong way. i.e invert the z translation to -360.0f.
See here for more information on OpenGL axis. If you translate an object n-units to the left, from the camera's point of view you have moved it n-units to the right.
your zNear plane shouldn't be negative
gluPerspective(45, width/height, 0.1, 1000);
have you tried placing the teapot at -360 ? . are you sure your view is looking towards +z and not -z
whats your scaling of the teapot?. Maybe it's just too tiny to be seen so far away

OpenGL change background without changing perspective of previously drawn pictures

So I draw an 'I' and use gluLookAt(0.f,0.f,3.f,0.f,0.f,0.f,0.f,1.f,0.f), and the I is moderate size. Then I add a drawScene() function which draw the background with gradient color, and then the 'I' becomes super big. I guess it is because I change matrix mode to GL_PROJECTION and GL_MODELVIEW in drawScene(), and those change the perspective maybe? I guess glPushMatrix() and glPopMatrix() are needed to reserve matrix status, but I have hard time finding where to put them. So how can I make the 'I' look normal size? Here are my drawI() and drawScene():
void drawI(int format)
{
glBegin(format);
glColor3f(0, 0, 1);
glVertex2f(point[3][0], point[3][1]);
glVertex2f(point[2][0], point[2][1]);
glVertex2f(point[1][0], point[1][1]);
glVertex2f(point[12][0], point[12][1]);
glVertex2f(point[10][0], point[10][1]);
glEnd();
glBegin(format);
glVertex2f(point[10][0], point[10][1]);
glVertex2f(point[11][0], point[11][1]);
glVertex2f(point[12][0], point[12][1]);
glEnd();
glBegin(format);
glVertex2f(point[9][0], point[9][1]);
glVertex2f(point[10][0], point[10][1]);
glVertex2f(point[3][0], point[3][1]);
glVertex2f(point[4][0], point[4][1]);
glVertex2f(point[6][0], point[6][1]);
glColor3f(1, 0.5, 0);
glVertex2f(point[7][0], point[7][1]);
glVertex2f(point[8][0], point[8][1]);
glEnd();
glBegin(format);
glColor3f(0, 0, 1);
glVertex2f(point[5][0], point[5][1]);
glVertex2f(point[6][0], point[6][1]);
glVertex2f(point[4][0], point[4][1]);
glEnd();
}
void drawScene()
{
glBegin(GL_QUADS);
//red color
glColor3f(1.0,0.0,0.0);
glVertex2f(-1.0,-1.0);
glVertex2f(1.0,-1.0);
//blue color
glColor3f(0.0,0.0,1.0);
glVertex2f(1.0, 1.0);
glVertex2f(-1.0, 1.0);
glEnd();
}
Thanks a lot!
So I take glMatrixMode() and glLoadIdentity() out of drawScene() and drawI() and put them in display(). I changed drawScene() and drawI() above, and here is my display()
void display()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70.f,1.f,0.001f,30.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
drawScene();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.f,0.f,3.f,0.f,0.f,0.f,0.f,1.f,0.f);
drawI(GL_TRIANGLE_FAN);
glutSwapBuffers();
}
The normal way to do this (in a 3D mode) is in your code, before you call drawI or drawScene would be:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fov, aspect, near, far); // fov is camera angle in degrees, aspect is width/height of your viewing area, near and far are your near and far clipping planes.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,0.0,3.0,0.0,0.0,0.0,0.0,1.0,0.0)
In your 2D rendering, you probably don't need the call to gluPerspective, but these calls should be done in your code before you call drawI or drawScene. Do this and delete the glMatrixMode() and glLoadIdentity() calls from drawI and drawScene.
Edit:
If your "I" is still too big, there are a number of things you could do, but you should probably be operating in 3D (giving a Z coordinate also).
You could scale the object:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,0.0,3.0,0.0,0.0,0.0,0.0,1.0,0.0)
glScalef(0.5, 0.5, 0.5);
You could move the camera further back (you'll need to include the gluPerspective() call as well):
gluLookAt(0.0,0.0,50.0,0.0,0.0,0.0,0.0,1.0,0.0);
Perhaps the easiest way to control the rendered image size in a 3D mode is to both move the camera (eye) back a way and then control the image size by changing the camera aperture angle (fov in the gluPerspective() call). A wider fov will shrink the rendered image; a smaller fov will enlarge it.
I don't know what the values for your coordinates are in drawI since they're variables, but a camera position of 3.0, an fov of 70.0 and an aspect of 1 should give you left, right, top and bottom clipping planes of about +/- 2.1 at Z = 0.
If you kept everything else the same and moved the camera to 50.0, the clipping planes would be at about +/- 35.0, so your "I" would occupy a much smaller portion of the viewing area.
If you then left the camera position at 50.0, but changed the fov to 40.0, the clipping planes would be at about +/- 18.2. Your "I" would fill a larger area than it did at cameraZ = 50.0, fov = 70.0, but a smaller area than cameraZ = 3.0, fov = 70.0.
You can play with camera position and fov to get the image size you want, or you could just scale the image. I like to keep camera position constant and change the fov. If I provide a function that changes the fov based on user input (maybe a mouse scroll), it's a good way to provide a zoom in/out effect.
BTW, in your original code, if you called:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,0.0,3.0,0.0,0.0,0.0,0.0,1.0,0.0)
Then later in DrawI or drawScene call:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
You've trashed the matrix loaded by your earlier call to gluLookAt().

How can I translate only one object of the scene in an OpenGL?

I have a wall pattern DrawWall and an airplane DrawAirplane in my OpenGL game. How can I push and pop the current matrix and translate only the wall in the scene?
I expect the airplane to be fixed.
private: void DrawWall(){
glPushMatrix();
glBegin(GL_POLYGON);
LeftWallPattern();
glEnd();
glBegin(GL_POLYGON);
RightWallPattern();
glEnd();
glPopMatrix();
}
private: void DrawAirplane(){
glPushMatrix();
glBegin(GL_LINE_LOOP);
//...
glEnd();
glPopMatrix();
}
public: void Display(){
glClear(GL_COLOR_BUFFER_BIT);
glTranslatef(0, -0.02, 0);
DrawWall();
DrawAirplane();
glFlush();
}
Use glPushMatrix() to push the current matrix, do glTranslate and draw the wall, then glPopMatrix() and draw the plane. This should only translate the wall. The problem is you seem to be doing the translate in display instead of in DrawWall where it should be.
A few things to expand on what Jesus was saying.
When drawing the airplane you don't want to apply any transformations to it, so you need to have the identity matrix loaded:
Push the current modelview matrix
Load the identity matrix <=== this is the step you're missing
Draw the airplane
Pop the modelview matrix
When drawing the wall you want the current transformations to apply, so you do not push the current matrix or else you've wiped out all of the translations you've built up.
Remove the Push/Pop operations from DrawWall()
At some point in your initialization, before Display is called for the first time, you need to set the modelview matrix to the identity matrix. For each subsequent call to Display, -0.02 will then be added to your translation in the y-direction.

Using glTranslate and glRotate to move and rotate?

I am writing an application that draws a 2D triangle and rotates it around its z-axis depending on its position. Its middle (t1.tx, t1.ty) is constantly being changed when the triangle is dragged with the mouse. The problem is that when I drag the triangle to another location, instead of staying where its at and rotating, it rotates in a circle path around its center point.
What I am doing wrong? I want it to rotate in its position.
void drawTriangle() {
glBegin(GL_POLYGON);
glColor3f((float)200/255, (float)200/255, (float)200/255);
glVertex2f(t1.tx, t1.ty + .2); // top point of triangle
glVertex2f(t1.tx - .2, t1.ty - .2); // left point
glVertex2f(t1.tx + .2, t1.ty - .2); // right point
glEnd();
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glPushMatrix();
glTranslatef(t1.tx, t1.ty, 0); // move matrix to triangle's current center point
glRotatef(theta, 0, 0, 1.0); // rotate on z-axis
drawTriangle();
glPopMatrix();
glutPostRedisplay();
glutSwapBuffers();
}
It has been a WHILE since I did this stuff, but based on what you are saying, my first guess would be to swap the order of the glTranslatef and glRotatef. You want to rotate in model space then transform to world space.
I fixed it. The problem was that I was translating the matrix, and then drawing onto that matrix that was translated. What I did was draw my triangle at the center of the matrix, so it still moves and rotates at its current position as the matrix is translated. Thank you for the help.

Rotation of camera used for perspective projection

I've just started playing with OpenGl to render a number of structure each comprising a number of polygon.
Basically I want to perform the equivalent of setting a camera at (0,0,z) in the world (structure) coordinates and rotate it about the x,y and z-axes of the world axes (in that order!) to render a view of each structure (as I understand it it common practice to do use the inverse camera matrix). Thus as I understand it I need to translate (to world origin i.e. (0,0,-z)) * rotateZrotateYrotateX * translate (re-define world origin see below)
So I think I need something like:
//Called when the window is resized
void handleResize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(9.148, (double)w / (double)h, 800.0, 1500.0);
}
float _Zangle = 10.0f;
float _cameraAngle = 90.0f;
//Draws the 3D scene
void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
glLoadIdentity(); //Reset the drawing perspective
glTranslatef(0.0f, 0.0f, -z); //Move forward Z (mm) units
glRotatef(-_Zangle, 0.0f, 0.0f, 1.0f); //Rotate "camera" about the z-axis
glRotatef(-_cameraAngle, 0.0f, 1.0f, 0.0f); //Rotate the "camera" by camera_angle about y-axis
glRotatef (90.0f,1.0f,0.0f,0.0f); // rotate "camera" by 90 degrees about x-axis
glTranslatef(-11.0f,189.0f,51.0f); //re-define origin of world coordinates to be (11,-189,-51) - applied to all polygon vertices
glPushMatrix(); //Save the transformations performed thus far
glBegin(GL_POLYGON);
glVertex3f(4.91892,-225.978,-50.0009);
glVertex3f(5.73534,-225.978,-50.0009);
glVertex3f(6.55174,-225.978,-50.0009);
glVertex3f(7.36816,-225.978,-50.0009);
.......// etc
glEnd();
glPopMatrix();
However when I compile and run this the _angle and _cameraAngle seem to be reversed i.e. _angle seems to rotate about y-axis (Vertical) of Viewport and _cameraAngle about z-axis (into plane of Viewport)? What am I doing wrong?
Thanks for taking the time to read this
The short answer is: Use gluLookAt(). This utility function creates the proper viewing matrix.
The longer answer is that each OpenGL transformation call takes the current matrix and multiplies it by a matrix built to accomplish the transformation. By calling a series of OpenGL transformation function you build one transformation matrix that will apply the combination of transformations. Effectively, the matrix will be M = M1 * M2 * M3 . . . Mathematically, the transformations are applied from right to left in the above equation.
Your code doesn't move the camera. It stays at the origin, and looks down the negative z-axis. Your transformations move everything in model space to (11,-189,-51), rotates everything 90 degrees about the x-axis, rotates everything 90 degrees about the y-axis, rotates everything 10 degrees about the z-axis, then translates everything -z along the z-axis.
EDIT: More information
I'm a little confused about what you want to accomplish, but I think you want to have elements at the origin, and have the camera look at those elements. The eye coordinates would be where you want the camera, and the center coordinates would be where you want the objects to be. I'd use a little trigonometry to calculate the position of the camera, and point it at the origin.
In this type of situation I usually keep track of camera position using longitude, latitude, and elevation centered on the origin. Calculating x,y,z for the eye coordinates is simplyx = elv * cos(lat) * sin(lon), y = elv * sin(lat), z = elv * cos(lat) * cos(lat).
My gluLookAt call would be gluLookAt(x, y, z, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
You could rotate the up on the camera by changing the last three coordinates for gluLookAt.
The z axis is coming from the center of the monitor into you. So, rotating around the z-axis should make the camera spin in place (like a 2D rotation on just the xy plane). I can't tell, but is that what's happening here?
It's possible that you are encountering Gimbal Lock. Try removing one of the rotations and see if things work the way they should.
While it's true that you can't actually move the camera in OpenGL, you can simulate camera motion by moving everything else. This is why you hear about the inverse camera matrix. Instead of moving the camera by (0, 0, 10), we can move everything in the world by (0, 0, -10). If you expand those out into matrices, you will find that they are inverses of each other.
I also noticed that, given the code presented, you don't need the glPushMatrix()/glPopMatrix() calls. Perhaps there is code that you haven't shown that requires them.
Finally, can you provide an idea of what it is you are trying to render? Debugging rotations can be hard without some context.
Short answer :Good tip
Longer answer: Yes the order of matrix multiplication is clear... that's what I meant by inverse camera matrix to indicate moving all the world coordinates of structures into the camera coordinates (hence the use of "camera" in my comments ;-)) instead of actually translating and rotating camera into the world coordinates.
So if I read between the lines correctly you suggest something like:
void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
glLoadIdentity(); //Reset the drawing perspective
gluLookAt(0.0,0.0,z,11.0,-189.0,-51.0,0.0,1.0,0.0); //eye(0,0,z) look at re-defined world origin(11,-189,-51) and up(0.0,1.0,0.0)
glRotatef(-_Zangle, 0.0f, 0.0f, 1.0f); //Rotate "camera" (actually structures) about the z-axis
glRotatef(-_cameraAngle, 0.0f, 1.0f, 0.0f); //Rotate the "camera" (actually structures!) by camera_angle about y-axis
glRotatef (90.0f,1.0f,0.0f,0.0f); // rotate "camera" (actually structures) by 90 degrees about x-axis
glPushMatrix();
Or am I still missing something?
I think you are mixing axes of your world with axes of the camera,
GLRotatef only uses axes of the camera, they are not the same as your the world axes once the camera is rotated.