# Getting Model View Matrix by hand

Right now I'm trying to calculate the model view matrix by hand... The App is 2D. I have something like this:

Vector2 Transform_GetUpVector(DeadTransform *transform, bool normalized)
{
Vector2 relative;
relative.x = 0;
relative.y = 1;

float sin = Sin(transform->angle),
cos = Cos(transform->angle);

Vector2 vector;
vector.x = relative.x * cos - relative.y * sin;
vector.y = relative.x * sin + relative.y * cos;

if (normalized)
vector = Vector2_Normalize(vector);

return vector;
}

{
Vector2 relative;
relative.x = 1;
relative.y = 0;

float sin = Sin(transform->angle),
cos = Cos(transform->angle);

Vector2 vector;
vector.x = relative.x * cos - relative.y * sin;
vector.y = relative.x * sin + relative.y * cos;

if (normalized)
vector = Vector2_Normalize(vector);

return vector;
}

Vector2 ScreenPointToSpace(struct Application *application, DeadCamera *camera, Vector2 point)
{
GLint viewport;
GLdouble //modelMatrix,
projectionMatrix;
GLdouble wz1 = 0, x = 0, y = 0;
glGetIntegerv(GL_VIEWPORT, viewport);
//glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projectionMatrix);

Vector2 r = Trasnform_GetRightVector(camera->gameObject->transform, true);
Vector2 u = Transform_GetUpVector(camera->gameObject->transform, true);

GLdouble matrix = {r.x, r.y, 0,      0,
u.x, u.y, 0,      0,
0,   0,   1,      0,
-camera->gameObject->transform->position->x / 1000, -camera->gameObject->transform->position->y / 1000, 0, 1 };

GLint realy = viewport - (GLint)point.y - 1;
gluUnProject((GLdouble)point.x, (GLdouble)realy, 0, matrix, projectionMatrix, viewport, &x, &y, &wz1);
Vector2 s;
s.x = (float)x * 1000;
s.y = (float)y * 1000;
return s;
}


But When I rotate the camera, the matrix is wrong.... why?

As you can see in this image the hammer cursor means that the cursor is touching a red circle area. But When I rotate the camera everything is at the wrong screen locations. • In what specific way does the behaviour you're seeing in game differ from what you expect? Jan 1 '19 at 23:02
• I'm using this with gluProject. It seems that the locations specified by gluProject get wrong. Jan 1 '19 at 23:58
• In what way are they wrong? I know this might seem like pestering, but knowing the exact symptoms you're seeing can help an experienced user identify the root cause much faster, helping you get better answers sooner when you include these details. Jan 2 '19 at 0:00
• I'm not quite following what it is you are having issues with? I am curious as to why you are using cos/sin operations. To begin viewing a 2D screen you simply need to set the View Matix to the Matrix Identity. Then you can edit the PositionX and PositionY value by simply setting there values keep in my your screen is a generally a 2by2 unit value so -1 through 1 would be your screen coordinates. You can convert pixel coordinates to screen coordinates by doing "((PosX*2 / ScreenWidth) - 1)" or "(PosY*2 / ScreenHeight) - 1)" or just move in small amounts like 0.01F. _41 = X, _42 = Y Jan 2 '19 at 1:57
• I'm using glutProject....I need the model view matrix.... but I can't use the one given by glGetDoublev From What I understand the model view matrix is given by a right or left ? vector an up vector a forward vector and the translation. The translation I got it right.... but for some reason the right and up vectors in matrix are giving me bad results I've edited the question so that you can see the gluproject Jan 2 '19 at 2:01

Ok Found a Way.... I was calculating the vectors incorrectly the angle should be converted. But I still don't get the matrix part... but here it goes

Vector2 Transform_GetUpVector(DeadTransform *transform, bool normalized)
{
Vector2 relative;
relative.x = 0;
relative.y = 1;

float sin = sinf(transform->angle * 3.14f / 180),
cos = cosf(transform->angle * 3.14f / 180);

Vector2 vector;
vector.x = relative.x * cos - relative.y * sin;
vector.y = relative.x * sin + relative.y * cos;

if (normalized)
vector = Vector2_Normalize(vector);

return vector;
}

{
Vector2 relative;
relative.x = 1;
relative.y = 0;

float sin = sinf(transform->angle * 3.14f / 180),
cos = cosf(transform->angle * 3.14f / 180);

Vector2 vector;
vector.x = relative.x * cos - relative.y * sin;
vector.y = relative.x * sin + relative.y * cos;

if (normalized)
vector = Vector2_Normalize(vector);

return vector;
}

Vector2 ScreenPointToSpace(struct Application *application, DeadCamera *camera, Vector2 point)
{
GLint viewport;
GLdouble //modelMatrix,
projectionMatrix;
GLdouble wz1 = 0, x = 0, y = 0;
glGetIntegerv(GL_VIEWPORT, viewport);
//glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projectionMatrix);

Vector2 r = Transform_GetRightVector(camera->gameObject->transform, true);
Vector2 u = Transform_GetUpVector(camera->gameObject->transform, true);

GLdouble matrix = {r.x, u.x, 0,  0,
r.y, u.y, 0,      0,
0,   0,   1,      0,
-camera->gameObject->transform->position->x / 1000, -camera->gameObject->transform->position->y / 1000, 0, 1 };

GLint realy = viewport - (GLint)point.y - 1;
gluUnProject((GLdouble)point.x, (GLdouble)realy, 0, matrix, projectionMatrix, viewport, &x, &y, &wz1);
Vector2 s;
s.x = (float)x * 1000;
s.y = (float)y * 1000;
return s;
}

• 3.14f -- this definitely should be a constant and have more precision, right now error margin is about 1/4deg. Jan 27 '20 at 6:50

I believe this should resolve some of your problem and it'll reduce your code quite a bit.

You can replace all that you had in that answer post with the following:

Vector2 ScreenPointToSpace(struct Application *application, DeadCamera *camera, Vector2 point)
{
GLint viewport;
GLdouble //modelMatrix,
projectionMatrix;
GLdouble wz1 = 0, x = 0, y = 0;
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_PROJECTION_MATRIX, projectionMatrix);

float radians = ((camera->gameObject->transform->angle) * 3.14f) / 180;

GLdouble matrix =
{
cos, sin, 0,  0,
sin, cos, 0,  0,
0,   0,   1,  0,
-camera->gameObject->transform->position->x / 1000, -camera->gameObject->transform->position->y / 1000, 0, 1
};

GLint realy = viewport - (GLint)point.y - 1;
gluUnProject((GLdouble)point.x, (GLdouble)realy, 0, matrix, projectionMatrix, viewport, &x, &y, &wz1);
Vector2 s;
s.x = (float)x * 1000;
s.y = (float)y * 1000;
return s;
}


In your code you were doing the following:

    cos, sin, 0,  0,
-sin, cos, 0,  0,


To give you an idea 0 Degrees would make it

1, 0, 0, 0
0, 1, 0, 0


Looks okay... since it matches the identity matrix.

But if you do let's say 45 degrees.

You would want to have

0.707, 0.707, 0, 0
0.707, 0.707, 0, 0


But you'll get the following instead.

 0.707, 0.707, 0, 0  //45 Degree Right Vector.
-0.707, 0.707, 0, 0  //225 Degree Up Vector.