-1

Edit: okay, I've written the code totally intuitive now and this is the result:

https://i.stack.imgur.com/oMZ0k.jpg

The Cube is at 0,0,0

As you can see, the camera position is negative on the z axis, suggesting that I'm viewing along the positive z axis, which does not match up. (fw is negative)

Also the cube colors suggest that I'm on the positive z axis, looking in the negative direction. Also the positive x-axis is to the right (in modelspace)

The angles are calculated like this:

    public virtual Vector3 Right
    {
        get
        {

            return Vector3.Transform(Vector3.UnitX, Rotation);
        }
    }
    public virtual Vector3 Forward
    {
        get
        {
            return Vector3.Transform(-Vector3.UnitZ, Rotation);
        }
    }
    public virtual Vector3 Up
    {
        get
        {
            return Vector3.Transform(Vector3.UnitY, Rotation);
        }
    }

Rotation is a Quaternion.

This is how the view and model matrices are creates:

    public virtual Matrix4 GetMatrix()
    {
        Matrix4 translation = Matrix4.CreateTranslation(Position);
        Matrix4 rotation = Matrix4.CreateFromQuaternion(Rotation);
        return translation * rotation;
    }

Projection:

    private void SetupProjection()
    {
        if(GameObject != null)
        {
            AspectRatio = GameObject.App.Window.Width / (float)GameObject.App.Window.Height;
            projectionMatrix = Matrix4.CreatePerspectiveFieldOfView((float)((Math.PI * Fov) / 180), AspectRatio, ZNear, ZFar);

        }
    }

Matrix multiplication:

    public Matrix4 GetModelViewProjectionMatrix(Transform model)
    {
        return  model.GetMatrix()* Transform.GetMatrix() * projectionMatrix;
    }

Shader:

[Shader vertex]
#version 150 core

in vec3 pos;
in vec4 color;
uniform float _time;
uniform mat4 _modelViewProjection;

out vec4 vColor;

void main() {
    gl_Position = _modelViewProjection * vec4(pos, 1);
    vColor = color;
}

OpenTK matrices are transposed, thus the multiplication order.

Any idea why the axis / locations are all messed up ?

End of edit. Original Post:

Have a look at this image: https://i.stack.imgur.com/OGKBk.jpg

As you can see, while the forward vector ( of the camera ) is positive in the z-Axis and the red cube is on the negative x axis,

float[] points = {
//  position (3) Color (3)
-s,  s, z, 1.0f, 0.0f, 0.0f, // Red point
 s,  s, z, 0.0f, 1.0f, 0.0f, // Green point
 s, -s, z, 0.0f, 0.0f, 1.0f, // Blue point
-s, -s, z, 1.0f, 1.0f, 0.0f, // Yellow point
};

(cubes are created in the geometry shader around those points)

the camera x position seems to be inverted. In other words, if I increase the camera position along its local x axis, it will move to the left, and vice versa.

I pass the transformation matrix like this:

        if (DefaultAttributeLocations.TryGetValue("modelViewProjectionMatrix", out loc))
        {
            if (loc >= 0)
            {
                Matrix4 mvMatrix = Camera.GetMatrix() * projectionMatrix;
                GL.UniformMatrix4(loc, false, ref mvMatrix);
            }

        }

The GetMatrix() method looks like this:

    public virtual Matrix4 GetMatrix()
    {
        Matrix4 translation = Matrix4.CreateTranslation(Position);
        Matrix4 rotation = Matrix4.CreateFromQuaternion(Rotation);

        return translation * rotation;
    }

And the projection matrix:

    private void SetupProjection()
    {
        AspectRatio = Window.Width / (float)Window.Height;
        projectionMatrix = Matrix4.CreatePerspectiveFieldOfView((float)((Math.PI * Fov)/180), AspectRatio, ZNear, ZFar);
    }

I don't see what I'm doing wrong :/

pixartist
  • 1,137
  • 2
  • 18
  • 40

2 Answers2

1

It's a little hard to tell from the code, but I believe this is because in OpenGL, the default forward vector of the camera is negative along the Z axis - yours is positive, which means you're looking at the model from the back. That would be why the X coordinate seems inverted.

vesan
  • 3,289
  • 22
  • 35
  • Well, no matter what I try, some axis always seems to be inverted. I think there is something weird in the openTK Matrix4 implementation. I'm gonna update this soon. – pixartist Jul 07 '14 at 16:56
  • Hmm... well, only think I can think of is that OpenTK Matrix4 is stored differently than OpenGL (OpenTK is row-major, OpenGL is column-major). But your transformations look good. Maybe try to shuffle them around a bit, see what it does... – vesan Jul 07 '14 at 22:43
  • If you use row-major matrices then you need to tell OpenGL that the matrices you are passing it are row-major. Look at the third parameter of glUniformMatrix4fv for example. Also, as vesan said, the default forward vector for the camera is (0, 0, -1). This means that you can't use the same lookAt function for the camera and your regular objects if your regular objects use (0, 0, 1) as their forward direction. You can create your projection matrix so that the camera looks down the positive z-axis. This will allow you to use the same lookAt function for everything. – Homar Jul 11 '14 at 04:10
1

Although this question is a few years old, I'd still like to give my input.

The reason you're experiencing this bug is because OpenTK's matrices are row major. All this really means is you have to do all matrix math is reverse. For example, the transformation matrix will be multiplied like so:

public static Matrix4 CreateTransformationMatrix(Vector3 position, Quaternion rotation, Vector3 scale)
{
    return Matrix4.CreateScale(scale) *
           Matrix4.CreateFromQuaternion(rotation) *
           Matrix4.CreateTranslation(position);
}

This goes for any matrix, so if you're using Vector3's instead of Quaternion's for your rotation it would look like this:

public static Matrix4 CreateTransformationMatrix(Vector3 position, Vector3 rotation, Vector3 scale)
{
    return Matrix4.CreateScale(scale) *
           Matrix4.CreateRotationZ(rotation.Z) *
           Matrix4.CreateRotationY(rotation.Y) *
           Matrix4.CreateRotationX(rotation.X) *
           Matrix4.CreateTranslation(position);
}

Note that your vertex shader will still be multiplied like this:

void main()
{
    gl_Position = projection * view * transform * vec4(position, 1.0f);
}

I hope this helps!