# 2 math issues running with OpenGL

I’m having trouble calculating my implentation of gluLookAt(). I get everything right and it matches OpenGL’s calculation’s except it doesn’t do anything to the eye vector. And I’ve looked at ton’s of examples. And none of them perform the exact calculations as OpenGL’s like if I move the center vector up the Y axis 5.0. It doesn’t move it just keeps pointing at the center of it. I tried mesa’s even and no luck.

Then the other problem I’m having is. My calculations with the Matrix. (Probably why it’s having trouble with gluLookAt implentation). But it always calculates a little different. Does exactly like OpenGL’s but misses a little for example.

if I do

glRotated(rot, 0.0, 1.0, 0.0);
glRotated(rot, 1.0, 0.0, 0.0);

and have of my own

Matrix4d tmp;
tmp.rotateYAxis(rot);
tmp.rotateXAxis(rot);
// glMultMatrix() is called underneath after every rotate.

Then OpenGL’s goes to the middle of the view. But mine goes all the way to the top on a 800x600 window mode screen.

``````
#ifndef MATRIX4_H_
#define MATRIX4_H_

#ifdef __GNUG__
#include <GL/gl.h>
#elif _MSC_VER
#include <windows.h>
#include <gl/gl.h>
#endif

#include <iostream>
#include <iomanip>
#include <cassert>
#include <algorithm>
#include "GLMath.h"
#include "Vector2.h"
#include "Vector3.h"
#include "Matrix3.h"

#ifdef __GNUG__
#define MAT4_INLINE __attribute__((always_inline))
#elif _MSC_VER
#define MAT4_INLINE __forceinline
#endif

template<typename Real>
//! Matrix4x4 Math class
class Matrix4
{
public:
union
{
Real mat[16];
struct
{
Real m11, m12, m13, m14,
m21, m22, m23, m24,
m31, m32, m33, m34,
m41, m42, m43, m44;
};
};

explicit Matrix4()
{
identity();
}

explicit Matrix4(Real m11, Real m21, Real m31, Real m41,
Real m12, Real m22, Real m32, Real m42,
Real m13, Real m23, Real m33, Real m43,
Real m14, Real m24, Real m34, Real m44)
{
mat[0] = m11; mat[4] = m21; mat[8] = m31; mat[12] = m41;
mat[1] = m12; mat[5] = m22; mat[9] = m32; mat[13] = m42;
mat[2] = m13; mat[6] = m23; mat[10] = m33; mat[14] = m43;
mat[3] = m14; mat[7] = m24; mat[11] = m34; mat[15] = m44;
}

Matrix4(const Matrix3<Real>& m)
{
mat[0] = m.mat[0]; mat[4] = m.mat[3]; mat[8] = m.mat[6];
mat[1] = m.mat[1]; mat[5] = m.mat[4]; mat[9] = m.mat[7];
mat[2] = m.mat[2]; mat[6] = m.mat[5]; mat[10] = m.mat[8];
}

Matrix4(const Matrix4& m)
{
for(unsigned i = 0; i < 16; ++i)
{
mat[i] = m.mat[i];
}
}

Matrix4(const Real* m)
{
for(unsigned i = 0; i < 16; ++i)
{
mat[i] = m[i];
}
}

MAT4_INLINE void operator=(const Matrix3<Real>& m)
{
mat[0] = m.mat[0]; mat[4] = m.mat[3]; mat[8] = m.mat[6];
mat[1] = m.mat[1]; mat[5] = m.mat[4]; mat[9] = m.mat[7];
mat[2] = m.mat[2]; mat[6] = m.mat[5]; mat[10] = m.mat[8];
}

MAT4_INLINE void operator=(const Matrix4& m)
{
for(unsigned i = 0; i < 16; ++i)
{
mat[i] = m.mat[i];
}
}

MAT4_INLINE void operator=(const Real* m)
{
for(unsigned i = 0; i < 16; ++i)
{
mat[i] = m[i];
}
}

MAT4_INLINE Matrix4 operator+(const Matrix4& m)
{
Matrix4 tmp;
for(unsigned i = 0; i < 16; ++i)
{
tmp.mat[i] = mat[i] + m.mat[i];
}
return tmp;
}

MAT4_INLINE void operator+=(const Matrix4& m)
{
(*this) = (*this) + m;
}

MAT4_INLINE Matrix4 operator+(const Real scalar)
{
Matrix4 tmp;
for(unsigned i = 0; i < 16; ++i)
{
tmp.mat[i] = mat[i] + scalar;
}
return tmp;
}

MAT4_INLINE void operator+=(const Real scalar)
{
(*this) = (*this) + scalar;
}

MAT4_INLINE Matrix4 operator-(const Matrix4& m)
{
Matrix4 tmp;
for(unsigned i = 0; i < 16; ++i)
{
tmp.mat[i] = mat[i] - m.mat[i];
}
return tmp;
}

MAT4_INLINE void operator-=(const Matrix4& m)
{
(*this) = (*this) - m;
}

MAT4_INLINE Matrix4 operator-(const Real scalar)
{
Matrix4 tmp;
for(unsigned i = 0; i < 16; ++i)
{
tmp.mat[i] = mat[i] - scalar;
}
return tmp;
}

MAT4_INLINE void operator-=(const Real scalar)
{
(*this) = (*this) - scalar;
}

MAT4_INLINE Matrix4 operator*(const Matrix4& m)
{
return Matrix4(mat[0] * m.mat[0] + mat[4] * m.mat[1] + mat[8] * m.mat[2] + mat[12] * m.mat[3],
mat[1] * m.mat[0] + mat[5] * m.mat[1] + mat[9] * m.mat[2] + mat[13] * m.mat[3],
mat[2] * m.mat[0] + mat[6] * m.mat[1] + mat[10] * m.mat[2] + mat[14] * m.mat[3],
mat[3] * m.mat[0] + mat[7] * m.mat[1] + mat[11]* m.mat[2] + mat[15] * m.mat[3],
mat[0] * m.mat[4] + mat[4] * m.mat[5] + mat[8] * m.mat[6] + mat[12] * m.mat[7],
mat[1] * m.mat[4] + mat[5] * m.mat[5] + mat[9] * m.mat[6] + mat[13] * m.mat[7],
mat[2] * m.mat[4] + mat[6] * m.mat[5] + mat[10] * m.mat[6] + mat[14] * m.mat[7],
mat[3] * m.mat[4] + mat[7] * m.mat[5] + mat[11] * m.mat[6] + mat[15] * m.mat[7],
mat[0] * m.mat[8] + mat[4] * m.mat[9] + mat[8] * m.mat[10] + mat[12] * m.mat[11]
mat[1] * m.mat[8] + mat[5] * m.mat[9] + mat[9] * m.mat[10] + mat[13] * m.mat[11],
mat[2] * m.mat[8] + mat[6] * m.mat[9] + mat[10] * m.mat[10] + mat[14] * m.mat[11],
mat[3] * m.mat[8] + mat[7] * m.mat[9] + mat[11] * m.mat[10] + mat[15] * m.mat[11],
mat[0] * m.mat[12] + mat[4] * m.mat[13] + mat[8] * m.mat[14] + mat[12] * m.mat[15],
mat[1] * m.mat[12] + mat[5] * m.mat[13] + mat[9] * m.mat[14] + mat[13] * m.mat[15],
mat[2] * m.mat[12] + mat[6] * m.mat[13] + mat[10] * m.mat[14] + mat[14] * m.mat[15],
mat[3] * m.mat[12] + mat[7] * m.mat[13] + mat[11] * m.mat[14] + mat[15] * m.mat[15]);
}

MAT4_INLINE void operator*=(const Matrix4& m)
{
(*this) = (*this) * m;
}

MAT4_INLINE Matrix4 operator*(const Real scalar)
{
Matrix4 tmp;
for(unsigned i = 0; i < 16; ++i)
{
tmp.mat[i] = mat[i] * scalar;
}
return tmp;
}

MAT4_INLINE void operator*=(const Real scalar)
{
(*this) = (*this) * scalar;
}

MAT4_INLINE bool operator==(const Matrix4& m)
{
for(unsigned i = 0; i < 16; ++i)
{
if(mat[i] != m.mat[i])
{
return false;
}
}
return true;
}

MAT4_INLINE bool operator!=(const Matrix4& m)
{
for(unsigned i = 0; i < 16; ++i)
{
if(mat[i] != m.mat[i])
{
return true;
}
}
return false;
}

MAT4_INLINE void identity()
{
for(unsigned i = 0; i < 16; ++i)
{
mat[i] = 0.0;
}
mat[0] = mat[5] = mat[10] = mat[15] = 1.0;
}

MAT4_INLINE void zero()
{
for(unsigned i = 0; i < 16; ++i)
{
mat[i] = 0.0;
}
}

MAT4_INLINE void translate(const Real x, const Real y, const Real z)
{
identity();
mat[12] = x;
mat[13] = y;
mat[14] = z;
this->multMatrix();
}

MAT4_INLINE void translate(const Vector3<Real>& v)
{
translate(v.x, v.y, v.z);
}

MAT4_INLINE void rotate(const Real angle, unsigned x, unsigned y, unsigned z)
{
if(angle == 0.0 || x == 0 && y == 0 && z == 0)
{
return;
}

Real sin = Math<Real>::sine(degrees);
Real cos = Math<Real>::cosine(degrees);

if (x == 0)
{
if (y == 0)
{
if(z != 0)
{
mat[0] = cos;
mat[5] = cos;

if(z < 0)
{
mat[1] = -sin;
mat[4] = sin;
}
else
{
mat[1] = sin;
mat[4] = -sin;
}
return;
}
}
else if(z == 0)
{
mat[0] = cos;
mat[10] = cos;

if(y < 0)
{
mat[2] = sin;
mat[8] = -sin;
}
else
{
mat[2] = -sin;
mat[8] = sin;
}
return;
}
}
else if(y == 0)
{
if(z == 0)
{
mat[5] = cos;
mat[10] = cos;
if(x < 0)
{
mat[6] = -sin;
mat[9] = sin;
}
else
{
mat[6] = sin;
mat[9] = -sin;
}
return;
}
}

Vector3<Real> tmp(x, y, z);
Real mag = tmp.magnitude();

if(mag <= 1.0e-4)
{
x /= mag;
y /= mag;
z /= mag;
}

Real  c = cos;
Real cm1 = 1.0 - c;
Real xx = x * x;
Real xy = x * y;
Real xs = x * sin;
Real yx = y * x;
Real yy = y * y;
Real yz = y * z;
Real zs = z * sin;
Real xz = x * z;
Real ys = y * sin;
Real zz = z * z;

mat[0] = (cm1 * xx) + c;  mat[4] = (cm1 * xy) - zs; mat[8] = (cm1 * xz) + ys;
mat[1] = (cm1 * yx) + zs; mat[5] = (cm1 * yy) + c;  mat[9] = (cm1 * yz) - xs;
mat[2] = (cm1 * xz) - ys; mat[6] = (cm1 * yz) + xs; mat[10] = (cm1 * zz) + c;
}

MAT4_INLINE void rotateXAxis(const Real angle)
{
rotate(angle, 1, 0, 0);
multMatrix();
}

MAT4_INLINE void rotateYAxis(const Real angle)
{
rotate(angle, 0, 1, 0);
multMatrix();
}

MAT4_INLINE void rotateZAxis(const Real angle)
{
rotate(angle, 0, 0, 1);
multMatrix();
}

MAT4_INLINE void lookAt(Vector3<Real>& eye, Vector3<Real>& centre, Vector3<Real>& up)
{
identity();
/*
Vector3<Real> forward(centre - eye);
forward.normalise();
Vector3<Real> side(forward.cross(up));
side.normalize();
Vector3<Real> upv(side.cross(forward));

mat[0] = side.x;     mat[4] = side.y;     mat[8]  = side.z;
mat[1] = up.x;       mat[5] = up.y;       mat[9]  = up.z;
mat[2] = -forward.x; mat[6] = -forward.y; mat[10] = -forward.z;
translate(-eye.x, -eye.y, -eye.z);*/

Vector3<Real> z = centre - eye;
z.normalise();
Vector3<Real> y = up;
Vector3<Real> x = y.cross(z);
y = z.cross(x);
x.normalise();
y.normalise();
eye = y.cross(eye);

mat[0] = x.x;
mat[1] = x.y;
mat[2] = x.z;

mat[4] = y.x;
mat[5] = y.y;
mat[6] = y.z;

mat[8] = z.x;
mat[9] = z.y;
mat[10] = z.z;

mat[12] = -eye.x;
mat[13] = -eye.y;
mat[14] = -eye.z;

multMatrix();
}

MAT4_INLINE Real* ptr()
{
return &mat[0];
}

MAT4_INLINE void transpose()
{
std::swap(mat[1], mat[4]);
std::swap(mat[2], mat[8]);
std::swap(mat[3], mat[12]);
std::swap(mat[6], mat[9]);
std::swap(mat[7], mat[13]);
std::swap(mat[11], mat[14]);
}

MAT4_INLINE void print()
{
for(unsigned i = 0; i < 4; ++i)
{
std::cout << std::fixed << std::setprecision(5)
<< "[ " << mat[i] << ", " << mat[i + 4] << ", " << mat[i + 8] << ", " << mat[i + 12] << " ]"
<< std::endl;
}
std::cout << std::endl;
}

{
}

MAT4_INLINE void multMatrix()
{
glMultMatrixImpl((*this).ptr());
}

{
}

{
}

MAT4_INLINE void glMultMatrixImpl(const double* d)
{
glMultMatrixd(d);
}

MAT4_INLINE void glMultMatrixImpl(const float* f)
{
glMultMatrixf(f);
}
};

typedef Matrix4<double> Matrix4d;
typedef Matrix4<float> Matrix4f;
typedef Matrix4d Mat4d;
typedef Matrix4f Mat4f;

#endif /*MATRIX4_H_*/

``````

I don’t really have time to look into your code but if I understand well, the camera orientation is good with the matrix you have built except the camera position?

Do you translate the scene from the opposite of the camera position before multiply the modelview matrix with your matrix?
Look at the end of this spec:
http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/glu/lookat.html