1

I'm currently working on my own 2D Maths library for my project to improve my understanding of the underlying matrix math. In the past I've use libraries such as GLM but I felt like it might be worth looking into as a learning experience.

Most of this has been straightforward and the majority of my Maths classes integrate and work well with OpenGL, however my view matrix appears to be stretching my quad at the edges of the window.

Note this isn't an issue of perspective, not only am I using an Orthographic Matrix but I've separated this from the MVP, using the view matrix in the place of the MVP and the issue still persists.

Below is my View Matrix generation code:

Matrix4x4 GenerateView(const Vector2f &cameraPosition)
{
    Matrix4x4 mat;

    //Right
    mat.elements[0][0] = 1;
    mat.elements[0][1] = 0;
    mat.elements[0][2] = 0;
    mat.elements[0][3] = -Dot(cameraPosition.x, cameraPosition.y, 10, 1, 0, 0);

    //Up
    mat.elements[1][0] = 0;
    mat.elements[1][1] = 1;
    mat.elements[1][2] = 0;
    mat.elements[1][3] = -Dot(cameraPosition.x, cameraPosition.y, 10, 0, 1, 0);

    //Look
    mat.elements[2][0] = cameraPosition.x;
    mat.elements[2][1] = cameraPosition.y;
    mat.elements[2][2] = -1;
    mat.elements[2][3] = -Dot(cameraPosition.x, cameraPosition.y, 10, cameraPosition.x, cameraPosition.y, -1);

    //Last Column
    mat.elements[3][0] = 0;
    mat.elements[3][1] = 0;
    mat.elements[3][2] = 0;
    mat.elements[3][3] = 1;
    return mat;
}

The Matrices are Column major (If I understand correctly). I was unclear whether the 'Look' was referring to a forward unit vector so I tried that as well as a 'center' but the issue persists.

//Look
    mat.elements[2][0] = 0;
    mat.elements[2][1] = 0;
    mat.elements[2][2] = -1;
    mat.elements[2][3] = -Dot(cameraPosition.x, cameraPosition.y, 10, 0, 0, -1);

Finally, in case anyone suspects that the Dot product is implemented incorrectly:

float Dot(float x1, float y1, float z1, float x2, float y2, float z2)
{
    return x1 * x2 + y1 * y2 + z1 * z2;
}
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
EightiethPeak
  • 197
  • 1
  • 6

1 Answers1

3

On the viewport the X-axis points to the left, the Y-axis up and the Z-axis out of the view (Note in a right hand system the Z-Axis is the cross product of the X-Axis and the Y-Axis).

view coordinate system

Note that a transformation matrix usually looks like this:

( X-axis.x, X-axis.y, X-axis.z, 0 )
( Y-axis.x, Y-axis.y, Y-axis.z, 0 )
( Z-axis.x, Z-axis.y, Z-axis.z, 0 )
( trans.x,  trans.y,  trans.z,  1 )

The code below defines a matrix that exactly encapsulates the steps necessary to calculate a look at the scene:

  • Converting model coordinates into viewport coordinates.
  • Rotation, to look in the direction of the view.
  • Movement to the eye position


Matrix4x4 LookAt( const Vector3f &pos, const Vector3f &target, const Vector3f &up )
{ 
    Vector3f mz( pos[0] - target[0], pos[1] - target[1], pos[2] - target[2] };
    Normalize( mz );
    Vector3f my( up[0], up[1], up[2] );
    Vector3f mx = Cross( my, mz );
    Normalize( mx );
    my = Cross( mz, mx );

    Matrix4x4 m;
    m.elements[0][0] = mx[0]; m.elements[0][1] = my[0]; m.elements[0][2] = mz[0]; m.elements[0][3] = 0.0f;
    m.elements[1][0] = mx[1]; m.elements[1][1] = my[1]; m.elements[1][2] = mz[1]; m.elements[1][3] = 0.0f;
    m.elements[2][0] = mx[2]; m.elements[2][1] = my[2]; m.elements[2][2] = mz[2]; m.elements[2][3] = 0.0f;

    m.elements[3][0] = Dot(mx, pos);
    m.elements[3][1] = Dot(my, pos);
    m.elements[3][2] = Dot(Vector3f(-mz[0], -mz[1], -mz[2]), pos);
    m.elements[3][3] = 1.0f;

    return m;
}

Vector3f Cross( const Vector3f &a, const Vector3f &b )
{ 
    return Vector3f( a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ); 
}

float Dot( const Vector3f &a, const Vector3f &b )
{ 
    return a[0]*b[0] + a[1]*b[1] + a[2]*b[2];
}

void Normalize( Vector3f &v )
{ 
    float len = sqrt( v[0] * v[0] + v[1] * v[1] + v[2] * v[2] );
    v = Vector3f( v[0] / len, v[1] / len, v[2] / len );
}
Rabbid76
  • 202,892
  • 27
  • 131
  • 174