Rotate scene around object at centre - opengl

I have an object which is at (0.0, 0.0, -39.0) and never moves, the rest of the scene moves relative to this object; I want the camera to look at this object and at the same direction. When I do this:
gluLookAt(0.0, 120.0, 10.0, 0.0, 0.0, -39.0, 0.0, 0.0, 1.0);
drawobject();
glTranslatef(0.0, y, 0.0);
glRotatef(angle, 0.0, 0.0, 1.0);
drawScene();
instead of scene rotating around object (actually around world z-axis), it rotates around its center. If I change the order of translation and rotation then it rotates around object correctly, but it translates in the direction of scene y-direction (I want it translate towards world y-direction). I think I know why this happens, but I don't know how to fix it. I guess I have made myself confused XD.
I should add that I use arrow keys to get input from user to change "y" and "angle". So, basically if this object is the player, I want the camera look at its back at all times, and player can move around using the keyboard. However, instead of moving the player, I decided to move the scene. I am not sure if this is the standard approach though.

Related

OpenGL transformation

I want to ask a question about transformation.
glPushMatrix();
glTranslatef(0.0, -10, 0.0);
glScalef(5000.0, 10.0, 5000.0);
glPushMatrix();
glColor3f(0,0,0);
glutSolidCube(1);
glColor3f(0.0, 0.0, 0.0);
glutWireCube(1);
glPopMatrix();
glPopMatrix();
The above code is the one I wrote to create a cube. In this case, I have understood the centre of the cube will be on y = -5. Did I understand correctly?
One of the great things about computer graphics is that you can always run the program and see what happens. And then swap the order of the translate and scale calls and run it again. You'll figure it out.
In this case, you may have difficulties because there's no reference to compare the cube to. I often use a little drawAxes() function, and recommend it to students, that just draws three lines from 0,0,0 to each of X=1, Y=1, Z=1. (Helps to draw the X line in red, Y in green, Z in blue.) Draw the axes as the very first thing you do so you've got a reference point, draw them again anytime you're not sure where a series of transformations will end up.

Why is this object drawn different if I use glFrustum?

I'm doing this OpenGL project for my Computer Graphics class, where I display an object and I rotate it and stuff, the thing is that at the beginning of the project we used glOrtho() and it looked really great.
But now the teacher said that we have to use glFrustum() for perspective and if I use that function, the object is drawn like this and I really don't know why does this happens:
This is my code from the init() function where everything changes:
void init (void)
{
/* select clearing (background) color */
glClearColor (0.0, 0.0, 0.0, 0.0);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-100.0, 100.0, -60.0, 160.0, -100.0, 100.0);
//glFrustum(-100, 100 ,-100 ,100 ,1 , 40);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(90,0,1,0);
}
I'd appreciate your help.
EDIT: If I use glFrustum(-100, 100, -100, 100, 20, 200) it looks like this, like I'm getting closer but what about the left, right, top and bottom parameters? Are they okay with that values?
It's hard to be certain without more information. Perhaps the model could give some insight. But I suspect it may have to do with your clipping planes (nearVal and farVal as described here) arguments passed to glFrustum (1, 40). Perhaps try setting them to a broader range like your glOrtho call: 1, 150 (Note: neither nearVal or farVal can be negative when passed to glFrustum).
This all depends on the scale of the model and how it is positioned relative to the camera. If part of the model falls outside of the clipping planes, then it will be, well... clipped.

Rotating 'camera' in OpenGL around object not object around camera

In my app I have a set of object lying around the scene. They are all grouped inside box. When user zoom out to see whole box and starts rotate it then the pivot point is in the middle of box,. When you zoom in to see specific object inside then rotating camera so that the object that you are looking at (or space in front of you) then they are still rotating around this previous pivot point.
What I would like to achieve is to have pivot point always in front of camera. In other words, when you zoom out and see box it rotates as it is doing now. When you zoom in to specific object/space then camera rotate around it.
I've created simple images to show what I mean - triangle is camera, red box is some object/space and orange circle is a path on which element is going on while rotating. The first one is what I have now, the second what I'd like to have.
I know that in OpenGL there isn't something like camera, so in fact it is whole world moving and not one point. So far I've created something like that:
glPushMatrix();
glTranslatef(translate[0], translate[1], translate[2]);
glRotatef(rot, 0.0, 1.0, 0.0);
DrawObject();
glPopMatrix();
translate is an array of values simulating camera movement.
EDIT:
After Ike answer I modified a little my code so now it looks like this:
glPushMatrix();
glTranslatef(pivot[0], pivot[1], pivot[2]);
glRotatef(rot, 0.0, 1.0, 0.0);
glTranslatef(translate[0], translate[1], translate[2]);
glPopMatrix();
So if I'm getting Iko's solution correctly now my biggest concern is calculating correctly pivot point according to place that I'm looking at. Is it correct thinking?
One way to get this kind of representation is to kind of translate the pivot to the origin, then rotate, and then step backwards, away from the pivot.
Effectively you translate in the opposite direction of the pivot (negative pivot, effectively moving it to the origin). Then rotate to the desired viewing angle. And then "step back" (translate along -Z in a right-handed coordinate system).
Something like this:
mat4 modelview_matrix(float distance, const vec3& pivot, const vec3& rotation_xyz)
{
mat4 distance_mat = tmat(0.0, 0.0, -distance);
mat4 rot_mat = rmat(rotation_xyz[0], rotation_xyz[1], rotation_xyz[2]);
mat4 pivot_mat = tmat(-pivot[0], -pivot[1], -pivot[2]);
return distance_mat * rot_mat * pivot_mat;
}
tmat and rmat above are basically just constructing translation and rotation matrices.
That allows you to orbit the camera around a pivot of your choice. Panning can be achieved by actually moving the pivot around, giving you those CAD-style viewport navigation controls.
So if I'm getting Iko's solution correctly now my biggest concern is
calculating correctly pivot point according to place that I'm looking
at. Is it correct thinking?
Pretty much -- maybe with a slight tweak. That pivot point will always be what you look at -- it's going to be your center of interest. You can, for example, put it at the center of the bounding box of your scene, e.g. (some 3D software does this to fit/frame the view around the scene). After that, it's up to you to place the pivot point where you like based on the kind of software design you're after. The camera will always be looking at it.
Edit
glPushMatrix();
glTranslatef(pivot[0], pivot[1], pivot[2]);
glRotatef(rot, 0.0, 1.0, 0.0);
glTranslatef(translate[0], translate[1], translate[2]);
glPopMatrix();
For this kind of thing, you probably want something more like this:
glTranslatef(-pivot[0], -pivot[1], -pivot[2]);
glRotatef(rot, 0.0, 1.0, 0.0);
glTranslatef(0, 0, -distance);
... and outside of pushing to the transformation stack and rendering individual objects (do this at the top of the call stack). That's what gives you something akin to "camera control".
Then when you render each object, push the current transformation and do the necessary local transformations for each object and child. That gives you something akin to objects moving around and being oriented in the world independently of the camera, and a motion hierarchy with parent-child relationships.

Move the camera in the direction its looking

I am rotating the camera around itself (when the camera is located at (0,0,0)) using the following:
glRotatef(x_camera_angle, 1.0, 0.0, 0.0);
glRotatef(y_camera_angle, 0.0, 1.0, 0.0);
I wish to move the camera in the direction its looking. For example, I want to move the camera 5 units right and 3 units forward. How can this be done?
I know that there's a lot of information out there, but I have yet to find a satisfying and simple answer.
Any help would be highly appreciated.
The best way is probably to translate before the rotate:
glTranslatef(5, 0, 3);
glRotatef(x_camera_angle, 1.0, 0.0, 0.0);
glRotatef(y_camera_angle, 0.0, 1.0, 0.0);

GL_MODELVIEW and GL_PROJECTION

My code Currently looks like this :
glViewport (0, 0, this->w(), this->h());
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
//glTranslated (m_fXmovement, 0.0, m_fZmovement - 5);
//glRotated (m_fYangleView, 1.0, 0.0, 0.0);
//glRotated (m_fXangleView, 0.0, 1.0, 0.0);
///// Model View \\\\\
glMatrixMode(GL_MODELVIEW);
glTranslated (m_fXmovement, 0.0, m_fZmovement - 5 );
glRotated (m_fYangleView, 1.0, 0.0, 0.0);
glRotated (m_fXangleView, 0.0, 1.0, 0.0);
DrawWaveFrontObject (m_pDataObjectMedia);
glPushMatrix();
glTranslated (0.0, -3.0, 0.0);
DrawArea();
glPopMatrix();
DrawClickAnimation();
glLoadIdentity();
First I had the movement part in GL_PROJECTION and all was running fine until I was working with fog.... It felt like the Camera isn't moving, it felt more like an additional camera pointing to that camera....
Then I accidentally copied the movement parts to the GL_MODELVIEW and the fog was acting as I wanted it to act..... all was fine accepting the click animation wasn't in relation to the area anymore, now the animation moved with my ego perspective.... and I don't really get it what kind of drawing I have to put in which of these two VIEW's. Could anyone give me examples or explanations according to my code or a hint what I could improve in my styl?
Quote from opengl.org forum:
The projection matrix is used to create your viewing volume. Imagine a
scene in the real world. You don't really see everything around you,
only what your eyes allow you to see. If you're a fish for example you
see things a bit broader. So when we say that we set up the projection
matrix we mean that we set up what we want to see from the scene that
we create. I mean you can draw objects anywhere in your world. If they
are not inside the view volume you won't see anything. When you create
the view volume imagine that you create 6 clipping planes that define
your field of view.
As for the modelview matrix, it is used to make various
transformations to the models (objects) in your world. Like this you
only have to define your object once and then translate it or rotate
it or scale it.
You would use the projection matrix before drawing the objects in your
scene to set the view volume. Then you draw your object and change the
modelview matrix accordingly. Of course you can change your matrix
midway of drawing your models if for example you want to draw a scene
and then draw some text (which with some methods you can work easier
in orthographic projection) then change back to modelview matrix.
As for the name modelview it has to do with the duality of modeling
and viewing transformations. If you draw the camera 5 units back, or
move the object 5 units forwards it is essentially the same.
First of all, I suggest that you try to abandon the fixed-function pipeline (glTranslate etc) since it's been deprecated for like 10 years now. Look here for a more modern tutorial if you're interested.
As for your problem, you can imagine the meaning of the two matrices like this: The projection matrix essentially captures properties intrinsic to the camera itself, like how its field of view is shaped.
On the other hand, the modelview matrix is composed of two parts, the model matrix and the view matrix. The model part is for transforming from object space (relative to an object itself) to world space. Then, the view part translates from there to the eye space, in which the camera sits at the origin and points down the (negative?) z axis. Together, the modelview matrix essentially states how objects are to be positioned relative to the camera.
For further information, this resource gives a detailed description of graphics transformations in the context of OpenGL.
[Jan, 2017] Edit: Pages from the first link seem to be unable to access these days, so there is another link to the same content from their archive.