Как правильно использовать GL.Ortho в OpenTK?

Я рисую некоторые фигуры, используя GLControl (OpenTK) в формах Windows. Однако проблема в том, что я не могу понять, как использовать метод 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. Однако я обнаружил, что Gl.Ortho2d не существует в OpenTK. Используя официальную документацию, я узнал, что между этими двумя не так уж и много различий, за исключением того факта, что при использовании Ortho2d параметры Near и Far неявно устанавливаются равными -1 и 1 соответственно.

Установив эти параметры, я получаю белый экран. Я хотел бы знать, что я делаю неправильно?

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: мне не нужны точные координаты для достижения результата на скриншоте. Я просто использую его для того, чтобы вы видели, что я пытаюсь сделать. Что я хотел бы понять, почему мое окно совершенно пустое, когда я использую Gl.Ortho2d.


person zmockus    schedule 18.03.2013    source источник


Ответы (2)


Проблема в том, что GL.Ortho() умножает текущую матрицу на орфографическую матрицу. Таким образом, с каждым отрендеренным кадром вы продолжаете умножать свою матрицу на новую орфографическую матрицу, и ваш вид уходит куда-то, где вы ничего не видите.

Измените его на что-то подобное, и вы увидите красивую анимацию:

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

Добавьте эти две строки перед вызовом GL.Ortho(), чтобы матрица была тождественной матрицей до того, как вы умножите ее на свою орфографическую матрицу.

GL.MatrixMode(MatrixMode.Projection);
GL.LoadIdentity();
person Markus Luedin    schedule 16.04.2013
comment
Да, GL.MatrixMode и Gl.LoadIdentity — ключевые строки здесь. Спасибо. :) - person zmockus; 19.06.2013

Так я делаю в своем проекте. Надеюсь, это поможет. Но я не помню, почему я сделал именно так.

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

person Gorkem    schedule 10.04.2013