0

我在 Windows 窗体中使用 GLControl (OpenTK) 绘制了一些图形。但是,问题是我无法弄清楚如何使用 GL.Ortho() 方法。

这是我写的代码:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void GlControlPaint(object sender, PaintEventArgs e)
    {
        GlControl.MakeCurrent();
        GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);


        GL.Viewport(150, 150, 300, 300);
        //GL.Ortho(0, 1, 0, 1, -1, 1);
        GL.ClearColor(Color.White);

        PaintSquareOrBorder(BeginMode.Quads, Color.Cyan, 0.2, 0.2, 0.45, 0.2, 0.45, -0.2, 0.2, -0.2);
        PaintSquareOrBorder(BeginMode.Quads, Color.Cyan, 0.1, -0.1, 0.1, 0.1, 0.2, 0.2, 0.2, -0.2);
        PaintSquareOrBorder(BeginMode.Quads, Color.Cyan, -0.2, -0.2, -0.45, -0.2, -0.45, 0.2, -0.2, 0.2);
        PaintSquareOrBorder(BeginMode.Quads, Color.Cyan, -0.1, 0.1, -0.1, -0.1, -0.2, -0.2, -0.2, 0.2);
        PaintSquareOrBorder(BeginMode.Quads, Color.Cyan, -0.1, 0.1, -0.2, 0.2, 0.2, 0.2, 0.1, 0.1);
        PaintSquareOrBorder(BeginMode.Quads, Color.Cyan, 0.1, -0.1, 0.2, -0.2, -0.2, -0.2, -0.1, -0.1);
        PaintSquareOrBorder(BeginMode.Quads, Color.Cyan, -0.2, 0.2, -0.2, 0.45, 0.2, 0.45, 0.2, 0.2);
        PaintSquareOrBorder(BeginMode.Quads, Color.Cyan, 0.2, -0.2, 0.2, -0.45, -0.2, -0.45, -0.2, -0.2);
        PaintSquareOrBorder(BeginMode.LineLoop, Color.Black, -0.1, -0.1, 0.1, -0.1, 0.1, 0.1, -0.1, 0.1);

        PaintBordersForMainFigure();



        GlControl.SwapBuffers();
        GlControl.Refresh();

    }

    private void PaintBordersForMainFigure()
    {
        PaintLine(Color.Black, 0.2, 0.2, 0.45, 0.2);
        PaintLine(Color.Black, 0.45, 0.2, 0.45, -0.2);
        PaintLine(Color.Black, 0.45, -0.2, 0.2, -0.2);
        PaintLine(Color.Black, 0.2, -0.2, 0.2, -0.45);
        PaintLine(Color.Black, 0.2, -0.45, -0.2, -0.45);
        PaintLine(Color.Black, -0.2, -0.45, -0.2, -0.2);
        PaintLine(Color.Black, -0.2, -0.2, -0.45, -0.2);
        PaintLine(Color.Black, -0.45, -0.2, -0.45, 0.2);
        PaintLine(Color.Black, -0.45, 0.2, -0.2, 0.2);
        PaintLine(Color.Black, -0.2, 0.2, -0.2, 0.45);
        PaintLine(Color.Black, -0.2, 0.45, 0.2, 0.45);
        PaintLine(Color.Black, 0.2, 0.45, 0.2, 0.2);
    }

    private static void PaintLine(Color color, double x1, double y1, double x2, double y2)
    {
        GL.Color3(color);

        GL.Begin(BeginMode.Lines);

        GL.Vertex2(x1, y1);
        GL.Vertex2(x2, y2);

        GL.End();
    }

    private static void PaintSquareOrBorder(BeginMode beginMode, Color color, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
    {
        GL.Color3(color);

        GL.Begin(beginMode);

        GL.Vertex2(x1, y1);
        GL.Vertex2(x2, y2);
        GL.Vertex2(x3, y3);
        GL.Vertex2(x4, y4);

        GL.End();
    }
}

这是我在没有 GL.Ortho 的情况下得到的结果:

这是我想用 GL.Ortho 得到的结果

但是如果我取消注释 GL.Ortho 代码,我会得到:

起初我想,因为我只使用 2d 对象,所以我应该使用 Ortho2D。但是,我发现 OpenTK 中不存在 Gl.Ortho2d。使用官方文档我发现,这两者之间没有太大区别,除了当使用 Ortho2d 时,near 和 far 参数分别隐式设置为 -1 和 1。

设置这些参数后,我得到一个白屏。我想知道,我做错了什么?

免责声明:我不需要确切的坐标来获得屏幕截图中的结果。我只是用它来让你看到我想要做什么。我想知道为什么当我使用 Gl.Ortho2d 时我的窗口是完全空白的。

4

2 回答 2

1

问题是 GL.Ortho() 将当前矩阵与正交矩阵相乘。因此,对于每个渲染帧,您都会不断地将矩阵与新的正交矩阵相乘,并且您的视图会漂移到您看不到任何东西的地方。

把它改成这样,你会看到一个漂亮的动画:

GL.Ortho(-0.99, 1, -0.99, 1, -1, 1);

在 GL.Ortho() 调用前面添加这两行,这样矩阵在与正交矩阵相乘之前是一个单位矩阵。

GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
于 2013-04-16T18:18:41.260 回答
0

这就是我在我的项目中所做的。希望有帮助。但我不记得为什么我这样做了。

GL.MatrixMode(MatrixMode.Projection);
Matrix4 ortho = Matrix4.CreateOrthographic(glControl1.Width, glControl1.Height, 10, 3000);
GL.LoadMatrix(ref ortho);
v = Matrix4.LookAt(0, 0, 100, 0, 0, 0, 0, 1, 0);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadMatrix(ref  v);

我的视口是 GL.Viewport(0, 0, glControl1.Width, glControl1.Height);

于 2013-04-10T15:03:41.693 回答