How to rotate and then move on that direction? - c++

Hy, I am currently trying to make a first person game.what i was able to do was to make the camera move using the function gluLookAt(), and to rotate it using glRotatef().What I am trying to to is to rotate the camera and then move forward on the direction i have rotated on, but the axes stay the same,and although i have rotated the camera moves sideways not forward. Can someone help me ? this is my code:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(cameraPhi,1,0,0);
glRotatef(cameraTheta,0,1,0);
gluLookAt(move_camera.x,move_camera.y,move_camera.z,move_camera.x,move_camera.y,move_camera.z-10,0,1,0);
drawSkybox2d(treeTexture);

This requires a bit of vector math...
Given these functions, the operation is pretty simple though:
vec rotx(vec v, double a)
{
return vec(v.x, v.y*cos(a) - v.z*sin(a), v.y*sin(a) + v.z*cos(a));
}
vec roty(vec v, double a)
{
return vec(v.x*cos(a) + v.z*sin(a), v.y, -v.x*sin(a) + v.z*cos(a));
}
vec rotz(vec v, double a)
{
return vec(v.x*cos(a) - v.y*sin(a), v.x*sin(a) + v.y*cos(a), v.z);
}
Assuming you have an orientation vector defined as {CameraPhi, CameraTheta, 0.0}, then if you want to move the camera in the direction of a vector v with respect to the camera's axis, you add this to the camera's position p:
p += v.x*roty(rotx(vec(1.0, 0.0, 0.0), CameraPhi), CameraTheta) +
v.y*roty(rotx(vec(0.0, 1.0, 0.0), CameraPhi), CameraTheta) +
v.z*roty(rotx(vec(0.0, 0.0, 1.0), CameraPhi), CameraTheta);
And that should do it.
Keep Coding :)

gluLookAt is defined as follows:
void gluLookAt(GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ,
GLdouble centerX, GLdouble centerY, GLdouble centerZ,
GLdouble upX, GLdouble upY, GLdouble upZ
);
The camera is located at the eye position and looking in the direction from the eye to the center.
eye and center together define the axis (direction) of the camera, and the third vector up defines the rotation about this axis.
You don't need the separate phi and theta rotations, just pass in the correct up vector to get the desired rotation. (0,1,0) means the camera is upright, (0,-1,0) means the camera is upside-down and other vectors define intermediate positions.

Related

OpenGL glulookat function

I want to be able to view a planet sphere centred 0,0,0 with 10 units radius, 360 degrees and up down by clicking my keyboard buttons. What parameters do I put inside the glulookat() function as?
I know the Center XYZ should be 000 but what should eye and up vector be?
void gluLookAt( GLdouble eyeX,
GLdouble eyeY,
GLdouble eyeZ,
GLdouble centerX,
GLdouble centerY,
GLdouble centerZ,
GLdouble upX,
GLdouble upY,
GLdouble upZ);
Don't use lookAt for this! The amount of trigonometry involved in calculating the eye vector is equivalent to building the view matrix from scratch.
Instead, maintain your camera pitch and yaw, and apply those by a series of translations and rotations:
glTranslatef(0, 0, -radius);
glRotatef(-pitch, 1, 0, 0);
glRotatef(-yaw, 0, 0, 1); // assumes Z is up

Can't understand gluLookAt arguments

I'm learning OpenGL (glut) now. By using GL_Lines I draw cube, but it looks like square so I tries to use gluLookAt. I've been searching and experimenting but I can't understand how it works! Help please.
As described in the documentation
C Specification
void gluLookAt(GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ,
GLdouble centerX, GLdouble centerY, GLdouble centerZ,
GLdouble upX, GLdouble upY, GLdouble upZ);
Parameters
eyeX, eyeY, eyeZ
Specifies the position of the eye point.
centerX, centerY, centerZ
Specifies the position of the reference point.
upX, upY, upZ
Specifies the direction of the up vector.
Description
gluLookAt creates a viewing matrix derived from an eye point, a reference point indicating the center of the scene, and an UP vector.
The matrix maps the reference point to the negative z axis and the eye point to the origin. When a typical projection matrix is used, the center of the scene therefore maps to the center of the viewport. Similarly, the direction described by the UP vector projected onto the viewing plane is mapped to the positive y axis so that it points upward in the viewport. The UP vector must not be parallel to the line of sight from the eye point to the reference point.
Borrowing the following image (source)
The eye would be P, the center would be fc, and up would be up. The "near plane" and "far plane" defined the extents of the viewing frustum

OpenGL glMatrixMode(GL_PROJECTION) vs glMatrixMode(GL_MODELVIEW)

what is the difference between placing glRotatef() after glMatrixMode(GL_PROJECTION);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glRotatef(red, green, blue);
and placing glRotatef() after glMatrixMode(GL_MODELVIEW);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(red, green, blue);
From documentation:
glMatrixMode() specifies which matrix is the current matrix.
GL_MODELVIEW - Applies subsequent matrix operations to the modelview matrix stack.
GL_PROJECTION - Applies subsequent matrix operations to the projection matrix stack.
What they are means?
If you set current matrix mode as projection (e.g glMatrixMode(GL_PROJECTION)), you are expected to change your projection matrix. Naturally, one of them are expected to be next line :
For orthographic projection:
glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);
gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top);
For perspective projection:
void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);
void gluPerspective(GLdouble fov, GLdouble aspect, GLdouble near, GLdouble far);
If you set current matrix mode as modelView(e.g glMatrixMode(GL_MODELVIEW)), you are saying that I am in the modelview matrix and I can apply basic operations to transform my objects like :
glRotatef();
glTranslatef();
glScalef();
In your question if you use rotatef after gl_projection instead of gl_modelview, you rotate your projection matrix which would corrupt your projection matrix.
`
OpenGL stores the Projection and ModelView matrixes separately, with the call to glMatrixMode() you specify which matrix you want to manipulate with the following calls.
So in the first example, you applying a rotation to the projection matrix, and in the second you apply it to the ModelView Matrix (which would be more common)
Also look at this answer for clarification Difference between glMatrixMode(GL_PROJECTION); and glMatrixMode(GL_MODELVIEW);

How to implement a smooth transition between two different camera view in opengl

gluLookAt is defined as follows
void gluLookAt(GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ,
GLdouble centerX, GLdouble centerY, GLdouble centerZ,
GLdouble upX, GLdouble upY, GLdouble upZ
);
I have two different cameras parameters corresponding to gluLookAt,I am confused about how to implement a smooth transition between views of these two camera parameters.
I hope that somebody can give me some cue or some code example.
I would consider using Spherical Linear Interpolation (slerp) on the rotations produced by gluLookAt (...). The GLM math library (C++) provides everything you need for this, including an implementation of LookAt.
Very roughly, this is what a GLM-based implementation might look like:
// Create quaternions from the rotation matrices produced by glm::lookAt
glm::quat quat_start (glm::lookAt (eye_start, center_start, up_start));
glm::quat quat_end (glm::lookAt (eye_end, center_end, up_end));
// Interpolate half way from original view to the new.
float interp_factor = 0.5; // 0.0 == original, 1.0 == new
// First interpolate the rotation
glm::quat quat_interp = glm::slerp (quat_start, quat_end, interp_factor);
// Then interpolate the translation
glm::vec3 pos_interp = glm::mix (eye_start, eye_end, interp_factor);
glm::mat4 view_matrix = glm::mat4_cast (quat_interp); // Setup rotation
view_matrix [3] = glm::vec4 (pos_interp, 1.0); // Introduce translation

Create a vector from a point to the x,y of the mouse, OpenGL, C++

I am trying to write a OpenGL application where an object is fired from a point( In this case 0,0,0 ) and flies to the x,y position of the mouse. This is the system I am currently using:
Create an object at the point 0,0,0
Get the x,y position of the mouse.
Convert the mouse to 3d co-ordinates.
Get a line between the start point and (mouse-X,m mouse-Y, far plane ) where the far plane is set to 4,294,967,295.
Use the parametric line equation to move the object along this line.
The problem is that the x,y on the far plane does not seem to correspond to the x,y mouse position so the object flies on the wrong line. I am pretty sure that the line/para,etric equation part is working ok, but the conversion between 2d and 3-d space may not. Here is what I have tried:
First convert to window co-ordinates:
POINT *mouse = new POINT();
mouse->x = mousePosition3D.x;
mouse->y = mousePosition3D.y;
ScreenToClient( windowHandle, mouse );
Then to 3-d co-ordinates
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLfloat winX, winY, winZ;
GLdouble posX, posY, posZ;
OBJ_TriCo returnMe;
//All matrices in use need to be retrived
glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
glGetDoublev( GL_PROJECTION_MATRIX, projection );
glGetIntegerv( GL_VIEWPORT, viewport );
//Set the co-ords to lookup, based on the mouse position passed to this
winX = (float)x;
winY = (float)viewport[3] - (float)y;
//Set the z to 0.99, for some reason the object will fly totally incorrectly otherwise
winZ = 0.999; //Get a point on the bettween FAR and NEAR-Clipping planes
//Convert the co-ords
gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
//Return there values
returnMe.x = posX;
returnMe.y = posY;
returnMe.z = posZ;
return returnMe;
I am wondering has any body do anything similar to this or what maths i may need to do to get the objects to fly along the correct line.
You can calculate world space ray direction from screen-space coordinates (normalized to range [-1, 1]) like this:
vec4f r = projection_to_view_matrix * vec4f(screen_x, screen_y, 0, 1);
vec3f rdir = transpose(world_to_view_rotation_matrix) * vec3f(r.x, r.y, r.z);