Задержка в позиции курсора рисования с SharpGL - PullRequest
0 голосов
/ 26 мая 2020

Я пытаюсь нарисовать позицию курсора квадратом при движении мыши.

Я использую SharpGL и OpenGLControl, но есть задержка между стрелкой курсора и нарисованным квадратом.

В событии MouseMove я сохраняю квадрат с центром в позиции мыши (отображаемый в _pointCursor, который представляет собой список вершин), затем в событии Draw элемента управления я рисую его:

private void DrawPointers(OpenGL gl)
{
    if (_pointCursor == null)
        return;
    SetColor(gl, Color.LightGray);
    gl.Begin(OpenGL.GL_LINE_LOOP);
    foreach (var item in _pointCursor)
    {
        gl.Vertex(item.X, item.Y, item.Z);
    }
    gl.End();

}

Есть ли какой-нибудь трюк, конфигурация или стратегия, чтобы избежать этой задержки?

Я думаю, проблема в том, как все нарисовано. Если я удалю DrawAxis() и DrawGrid(), задержки больше не будет. В этом случае это может зависеть от моей стратегии рисования, я использую много gl.Begin() и gl.End().

Другое дело, что DrawGrid() и DrawAxis() продолжают рисовать фиксированный фон. Я не использую шейдеры.

Это код:

private void MouseDrawCursors(XglVertex v)
{
    if ((_view == ViewType._2D) && ((_status == EditStatus.Idle) || (_status == EditStatus.DrawLine)))
    {
        _pointCursor = v.DrawSquare(0.1f); //Return a list of vertex
        _pointCross = v.DrawCross(20); //Return a list of vertex
    }
}

private void openGLControl1_MouseMove(object sender, MouseEventArgs e)
{
    if (_gl == null)
        return;

    double worldX = 0;
    double worldY = 0;
    double worldZ = 0;
    _gl.GetWorldCoords(e.X, e.Y, ref worldX, ref worldY, ref worldZ);
    XglVertex v = new XglVertex((float)worldX, (float)worldY, (float)worldZ);

    MouseDrawCursors(v);
}

private void Draw()
{
    if (_gl == null)
        return;

    //Enable 3D
    if (_view == ViewType._2D)
        _gl.Disable(OpenGL.GL_DEPTH_TEST);
    else
        _gl.Enable(OpenGL.GL_DEPTH_TEST);
    _gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);

    //Enable  Aplpha
    _gl.Enable(OpenGL.GL_BLEND);
    _gl.BlendFunc(OpenGL.GL_SRC_ALPHA, OpenGL.GL_ONE_MINUS_SRC_ALPHA);

    #region Projection

    _gl.MatrixMode(OpenGL.GL_MODELVIEW);
    _gl.LoadIdentity();

    _gl.Scale(Params.ScaleFactor, Params.ScaleFactor, Params.ScaleFactor);
    _gl.Translate(Params.X, Params.Y, Params.Z);

    if (_status == EditStatus.Rotate)
        _arc_ball_effect.ArcBall.TransformMatrix(_gl);
    else
        _gl.Rotate(Params.XAngle, Params.YAngle, Params.ZAngle);

    _gl.MatrixMode(OpenGL.GL_PROJECTION); //matrice di proiezione
    _gl.LoadIdentity(); //ripristina matrice identità

    float worldWidth = Params.Width;
    float worldHeight = Params.Height;
    float near = Params.Near;
    float far = Params.Far;

    _gl.Viewport(0, 0, openGLControl1.Width, openGLControl1.Height);

    if (_aspect_ratio >= 1.0)
        _gl.Ortho(0, (worldWidth * _aspect_ratio), 0, worldHeight, near, far);
    else
        _gl.Ortho(0, worldWidth, 0, (worldHeight / _aspect_ratio), near, far);

    #endregion

    if (Params.ShowPointers)
        DrawPointers(_gl);

    if (Params.ShowAxis)
        DrawAxis(_gl);

    if (Params.ShowGrid)
        DrawGrid(_gl);

    _gl.Flush();
}

private void DrawPointers(OpenGL gl)
{
    if (_pointCursor == null)
        return;

    if (_pointCursor.Count == 0)
        return;

    SetColor(gl, Color.LightGray);
    gl.Begin(OpenGL.GL_LINE_LOOP);
    foreach (var item in _pointCursor)
    {
        gl.Vertex(item.X, item.Y, item.Z);
    }
    gl.End();


    if (_pointCross == null)
        return;
    SetColor(gl, Color.LightGreen);
    gl.Begin(OpenGL.GL_LINES);
    foreach (var item in _pointCross)
    {
        gl.Vertex(item.X, item.Y, item.Z);
    }
    gl.End();

}


private void DrawGrid(OpenGL gl)
{
    if (_gl == null)
        return;

    if (_grid == null)
        return;

    if (!Params.ShowGrid)
        return;

    SetColor(gl, _grid.GridColor);

    if (_grid.EnableXY)
    {
        gl.Begin(OpenGL.GL_POINTS);
        foreach (var p in _grid.XY)
        {
            gl.Vertex(p.X, p.Y, p.Z);
        }
        gl.End();
    }

    if (_grid.EnableYZ)
    {
        gl.Begin(OpenGL.GL_POINTS);
        foreach (var p in _grid.YZ)
        {
            gl.Vertex(p.X, p.Y, p.Z);
        }
        gl.End();
    }

    if (_grid.EnableZX)
    {
        gl.Begin(OpenGL.GL_POINTS);
        foreach (var p in _grid.ZX)
        {
            gl.Vertex(p.X, p.Y, p.Z);
        }
        gl.End();
    }
}
...