You can find them in GLM (as functions perspective and lookat)
but I am using Eigen, and after a long reflexion with myself, I decided to stay with Eigen.
I made a version of perspective and lookat for Eigen:
#include "Eigen/Core"
template<class T>
Eigen::Matrix<T,4,4> perspective
(
double fovy,
double aspect,
double zNear,
double zFar
)
{
typedef Eigen::Matrix<T,4,4> Matrix4;
assert(aspect > 0);
assert(zFar > zNear);
double radf = Math::degToRad(fovy);
double tanHalfFovy = tan(radf / 2.0);
Matrix4 res = Matrix4::Zero();
res(0,0) = 1.0 / (aspect * tanHalfFovy);
res(1,1) = 1.0 / (tanHalfFovy);
res(2,2) = - (zFar + zNear) / (zFar - zNear);
res(3,2) = - 1.0;
res(2,3) = - (2.0 * zFar * zNear) / (zFar - zNear);
return res;
}
template<class T>
Eigen::Matrix<T,4,4> lookAt
(
Eigen::Matrix<T,3,1> const & eye,
Eigen::Matrix<T,3,1> const & center,
Eigen::Matrix<T,3,1> const & up
)
{
typedef Eigen::Matrix<T,4,4> Matrix4;
typedef Eigen::Matrix<T,3,1> Vector3;
Vector3 f = (center - eye).normalized();
Vector3 u = up.normalized();
Vector3 s = f.cross(u).normalized();
u = s.cross(f);
Matrix4 res;
res << s.x(),s.y(),s.z(),-s.dot(eye),
u.x(),u.y(),u.z(),-u.dot(eye),
-f.x(),-f.y(),-f.z(),f.dot(eye),
0,0,0,1;
return res;
}
and easy to use:
...
typedef Eigen::Matrix4f Matrix4;
typedef Eigen::Vector3f Vector3;
float fovy = ...;
float ratio = ...;
float near_plan = ...;
float far_plan = ...;
Matrix4 projectionMatrix = perspective<Matrix4::Scalar>(
fovy,
ratio,
near_plan,
far_plan
);
Vector3 eye, center, eyeUp;
... init code ...
Matrix4 cameraMatrix = lookAt( eye, center, eyeUp );
if you are using OpenGL 2.1 then you can use them as:
glLoadMatrixf( projectionMatrix.data() );
if you are using OpenGL 2.1 then you can use them as:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glLoadMatrixf( projectionMatrix.data() );
and
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLoadMatrixf(cameraMatrix.data());Hope it will be useful for you as well, let me know if it was.
:-)