X轴在OpenTK中似乎是倒置的

时间:2014-07-05 15:57:48

标签: opengl matrix position axis opentk

编辑:好的,我现在编写的代码非常直观,结果就是这样:

http://i.imgur.com/x5arJE9.jpg

多维数据集位于0,0,0

如您所见,相机位置在z轴上为负,表明我正在沿正z轴观察,这与z轴不匹配。 (fw是否定的)

此外,立方体颜色表明我在正z轴上,向负方向看。正x轴也在右侧(在模型空间中)

角度计算如下:

    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);
        }
    }

旋转是一个四元数。

这是视图和模型矩阵的创建方式:

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

投影:

    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);

        }
    }

矩阵乘法:

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

着色器:

[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矩阵是转置的,因此是乘法顺序。

知道为什么轴/位置都搞砸了吗?

编辑结束。原帖:

看一下这张图片:http://i.imgur.com/Cjjr8jz.jpg

正如你所看到的,虽然前向矢量(摄像机)在z轴上是正的而红色的立方体在负x轴上,

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
};

(在这些点周围的几何着色器中创建立方体)

相机x位置似乎是倒置的。换句话说,如果我沿着局部x轴增加摄像机位置,它将向左移动,反之亦然。

我像这样传递变换矩阵:

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

        }

GetMatrix()方法如下所示:

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

        return translation * rotation;
    }

投影矩阵:

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

我看不出我做错了什么:/

2 个答案:

答案 0 :(得分:1)

从代码中可以很难说出来,但我相信这是因为在OpenGL中,相机的默认前向矢量沿着Z轴是负的 - 你的是肯定的,这意味着你是从后面看模型。这就是X坐标似乎倒转的原因。

答案 1 :(得分:1)

虽然这个问题已经有几年了,但我仍然愿意提出意见。

您遇到此错误的原因是因为OpenTK的矩阵是行主要的。这一切真正意味着你必须做所有的矩阵数学是相反的。例如,变换矩阵将如此相乘:

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

这适用于任何矩阵,因此如果你使用Vector3而不是Quaternion进行轮换,它将如下所示:

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);
}

请注意,您的顶点着色器仍将成倍增加:

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

我希望这有帮助!