I have a program to do augmented reality and in OpenGL I use :
glFrustum(-near*centerImageX/(GLfloat)fx, near*(imageWidth-centerImageX)/(GLfloat)fx, near*(centerImageY-imageHeight)/(GLfloat)fy, near*centerImageY/(GLfloat)fy, near, far);
This is ok, I get the good perspective and my 3D object is well inserted on my photo. Now I would like to be able to zoom in/out. Normally, it's done by changing fov in gluPerspective but I don't use gluPerspective because I can't get a good insertion.
With http://dmi.uib.es/~josemaria/files/OpenGLFAQ/transformations.htm, question "9.085 How can I make a call to glFrustum() that matches my call to gluPerspective()?", I tried with :
fov=360.0*atan(imageHeight/(2*fy))/Pi; //computed with parameters top and bottom of my glFrustum
aspect=-centerImageY*fx/(fy*(centerImageX-imageWidth)); //computed with parameters left and bottom of my glFrustum
void glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);
void gluPerspective( GLdouble fovy, GLdouble aspect,GLdouble near, GLdouble far );
And then :
gluPerspective(fov, aspect, near, far);
But my object is distorted, it's not scaled correctly on all axes, ratio is not kept.
So what do I need to do / modify in my glFrustum parameters to get a zoom in / out effect ?
Normally, it's not done by changing the fov in
gluPerspective()
.Normally, you would apply transformations to the model and/or view matrix for that matter. If you want to move the model, you usually do that in the Model Matrix. If you want to change "the camera position", you usually do that in the View Matrix.
In your case, you would probably translate the View Matrix. As that would resolve in the illusion of your 3D object moving away or coming up closer to the camera.
If you're still using the fixed-function pipeline, you can perform these changes, by calling some of the following functions.
glMatrixMode(x);
- Where x is eitherGL_PROJECTION_MATRIX
orGL_MODELVIEW_MATRIX
glLoadIdentity();
- "Resets" the current selected matrix.glTranslate*(x, y, z);
glRotate*(angle, x, y, z);
glScale*(x, y, z);
Though, if you're using modern OpenGL then don't use the above (which you also really can't then). Instead you want to calculate all the matrix transformations yourself and pass them to your shader. If you don't want to calculate all those advanced matrix operations yourself, you can get something like GLM (OpenGL Mathematics).