为什么渲染变成黑色

时间:2017-09-02 13:45:36

标签: c# winforms rendering buffering

我正在使用眼动仪来显示表格上的眼球运动。这些动作一直闪烁很多,所以我发现我可以使用BufferedGraphics,除了眼球运动开始时,它的形状从原始颜色变为黑色。这是代码。希望有人可以提供帮助!

private void button2_Click(object sender, EventArgs e)
{
    var host = new Host();
    var gazeStream = host.Streams.CreateGazePointDataStream();
    gazeStream.GazePoint((x, y, ts) 
         => drawCircle(new PointF((float)x, (float)y)));
}

delegate void SetCallback(PointF point);

private void drawCircle(PointF point)
{
    float x = point.X;
    float y = point.Y;

    if (this.InvokeRequired)
    {
        SetCallback d = new SetCallback(drawCircle);
        this.Invoke(d, new object[] { point });
    }
    else
    {
        SolidBrush semiTransBrush = new SolidBrush(Color.Coral);
        Pen pen = new Pen(Color.Aquamarine, 2);

        BufferedGraphicsContext currentContext;
        BufferedGraphics myBuffer;
        // Gets a reference to the current BufferedGraphicsContext
        currentContext = BufferedGraphicsManager.Current;
        // Creates a BufferedGraphics instance associated with Form1, and with 
        // dimensions the same size as the drawing surface of Form1.
        myBuffer = currentContext.Allocate(this.CreateGraphics(),this.DisplayRectangle);
        myBuffer.Graphics.DrawEllipse(pen, x, y, 100, 100);
        myBuffer.Graphics.FillEllipse(semiTransBrush, x, y, 100, 100);


        // Renders the contents of the buffer to the specified drawing surface.
        myBuffer.Render(this.CreateGraphics());

        myBuffer.Dispose();
    }

enter image description here

你可以在图像中看到圆圈出现在控件后面,看起来表格已经消失了吗?

1 个答案:

答案 0 :(得分:1)

分配缓冲区时,它会使用您提供的图形创建兼容的渲染表面。但它不会复制它或其他任何东西,所以如果你只画一个圆圈,剩下的部分仍然是黑色的。

BufferedGraphics真的可以帮助你避免在特殊情况下闪烁(例如,当出于某种原因必须禁用系统双缓冲时),但这里是一个过度杀伤。

因此关键是启用双缓冲并在Paint事件(或OnPaint方法)中执行每个绘制。在你的代码中,你立即绘画,总是闪烁。相反,您应该使表单无效并让系统执行常规重绘会话,如果您愿意,可以使用双缓冲。

进入构造函数:

SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);

然后修改点击事件:

private PointF lastGazePoint;

private void button2_Click(object sender, EventArgs e)
{
    var host = new Host();
    var gazeStream = host.Streams.CreateGazePointDataStream();
    gazeStream.GazePoint((x, y, ts) => 
        {
            lastGazePoint = new PointF((float)x, (float)y);
            Invalidate();
        });
 }

绘画本身:

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    DrawCircle(e.Graphics, lastGazePoint.X, lastGazePoint.Y);
}

最后,修改DrawCircle以使用Graphics中的PaintEventArgs

private void DrawCircle(Graphics g, float x, float y)
{
    using (Brush semiTransBrush = new SolidBrush(Color.Coral))
    {
        using (Pen pen = new Pen(Color.Aquamarine, 2))
        {
            g.DrawEllipse(pen, x, y, 100, 100);
            g.FillEllipse(semiTransBrush, x, y, 100, 100);
        }        
    }        
}