opentk俯仰旋转使形状变形

时间:2014-06-02 04:22:26

标签: 3d opentk pitch

我在c#中使用opentk来渲染3d表面并旋转它。 偏航工作正常,但俯仰旋转(使物体朝向摄像机倾斜)会导致表面变形。 enter image description here

左边的图像是我正在渲染的变形而右边的图像是正确的。 请注意,当音高为零时,它看起来非常精细。 以下是我的代码的要点:

private void glControl1_Paint(object sender, PaintEventArgs e)
{
    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
    Matrix4 perspective = Matrix4.CreatePerspectiveFieldOfView(1.0f, aspect_ratio, 1.0f, 10000.0f); //Setup Perspective [fovy, aspect, zNear, zFar]
    Matrix4 lookat = Matrix4.LookAt(eye_pos.X, eye_pos.Y, eye_pos.Z, 0, 0, 0, 0, 0, 1); //Setup camera   [eyeX, eyeY, eyeZ, targetX, targetY, targetZ, upX, upY, upZ)]

    GL.MatrixMode(MatrixMode.Projection); //Load Perspective
    GL.LoadIdentity();
    GL.Viewport(0, 0, this.ClientSize.Width, this.ClientSize.Height);
    GL.LoadMatrix(ref perspective);
    GL.MatrixMode(MatrixMode.Modelview); //Load Camera
    GL.LoadIdentity();
    GL.LoadMatrix(ref lookat);
    GL.Viewport(0, 0, glControl1.Width, glControl1.Height); //Size of window
    GL.Enable(EnableCap.DepthTest); //Enable correct Z Drawings
    GL.DepthFunc(DepthFunction.Less); //Enable correct Z Drawings

    //Rotating
    Vector2 xy_view_vector = new Vector2(eye_pos.X, eye_pos.Y);
    xy_view_vector.Normalize();
    Vector2 fold_vec = xy_view_vector.PerpendicularLeft; // this is the line over which you'd tilt the view forward towards the camera
    GL.Rotate((float)numericUpDown2.Value, fold_vec.X, fold_vec.Y, 0.0f);// pitch (tilt forward)
    GL.Rotate((float)numericUpDown1.Value, 0.0f, 0.0f, 1.0f);// yaw rotation - about z


    // axes
    GL.Begin(PrimitiveType.Lines);
    GL.Color3(Color.White);
    GL.Vertex3(-10, 0, 0);
    GL.Vertex3(10, 0, 0);
    GL.Vertex3(0, -10, 0);
    GL.Vertex3(0, 10, 0);
    GL.Vertex3(0, 0, -10);
    GL.Vertex3(0, 0, 10);
    GL.End();

    int i2, j2;
    float z1, z2, z3, z4;
    GL.Begin(PrimitiveType.Quads);
    for (int i = 0; i < data.x.Count - 2; i++)
    {
        for (int j = 0; j < data.y.Count - 2; j++)
        {
            i2 = i + 1;
            j2 = j + 1;
            z1 = data.z[i.ToString() + "," + j.ToString()];
            z2 = data.z[i2.ToString() + "," + j.ToString()];
            z3 = data.z[i2.ToString() + "," + j2.ToString()];
            z4 = data.z[i.ToString() + "," + j2.ToString()];
            GL.Color4(color_map.GetColor((z1 + z3) / 2, data.minz, data.maxz, opacity));

            GL.Vertex3(new Vector3(data.x[i], data.y[j], z1));
            GL.Vertex3(new Vector3(data.x[i2], data.y[j], z2));
            GL.Vertex3(new Vector3(data.x[i2], data.y[j2], z3));
            GL.Vertex3(new Vector3(data.x[i], data.y[j2], z4));
        }
    }
    GL.End();

    GraphicsContext.CurrentContext.VSync = true; //Caps frame rate as to not over run GPU
    glControl1.SwapBuffers(); //Takes from the 'GL' and puts into control
}

我想知道是否有人知道为什么会这样。 有一个简单的俯仰/偏航旋转样本会有所帮助 - 所以如果你知道一个可以提供帮助的opentk样本,我会很感激它的链接。

1 个答案:

答案 0 :(得分:2)

我无法确切地告诉你你做错了什么,但是我可以粘贴我用来围绕原点对象旋转相机的代码:

void SetupPerspective()
{
    var aspectRatio = Width / (float)Height;
    Projection = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspectRatio, 0.1f, 10);
    ModelView = Matrix4.Identity;
    // apply camera transform
    Camera.ApplyCamera(ref ModelView);
}

void ApplyCamera(ref Matrix4 modelView)
{
    modelView = Matrix4.CreateRotationY(Yaw)
        * Matrix4.CreateRotationX(Pitch)
        * Matrix4.CreateRotationZ(Roll)
        * Matrix4.CreateTranslation(-Position)
        * modelView;
}

我没有使用固定功能管道,但您可以设置生成的Projection和ModelView矩阵,就像您已经在使用它一样。