C#图形编程之GDI绘图:(三) 商用级之双缓冲

在上一篇文章 C#图形编程之GDI绘图:(三) 普通级之双缓冲 中我们介绍了两种双缓冲的机制,通过编码实现了第一种方式,在计算量较少的场景下得到了比较满意的效果。但是当计算了较大时,刷新就出现了卡顿。

本篇文章介绍第二种双缓冲方式。再来回顾下我们的代码:

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            //黑色底清屏
            e.Graphics.Clear(Color.Black);

            //第一次输出fps
            //实际上这里是不需要的,但由于入门级的绘制太慢,如果不在绘制前输出,就看不到了
            e.Graphics.DrawString(string.Format("fps: {0}", (int)fps), Font, Brushes.Yellow, 10, 20);

            //绘制小方格,并根据坐标变化实现上移滚动效果
            int size = 1;
            int xCount = panel1.Width / size + 1;
            int yCount = panel1.Height * 2 / size + 1;
            for (int i=0; i< xCount; i++)
            {
                for (int j = 0; j < yCount; j++)
                {
                    int left = i * size * 2;
                    int top = j * size * 2 - start_top - size * 2;
                    Rectangle rectItem = new Rectangle(left, top, size, size);
                    e.Graphics.FillRectangle(Brushes.AliceBlue, rectItem);
                }
            }

            //计算fps
            calculateFPS();

            //第二次输出fps
            e.Graphics.DrawString(string.Format("fps: {0}", (int)fps), Font, Brushes.Yellow, 10, 20);
        }

最耗时间的无疑是两个for循环,如果是500*500像素的界面大小,每次刷新都要做25万次的操作,这太恐怖了。所以这里是我们要优化的关键点。事实上,每次重复的绘制工作都是一样的,只是坐标不同,我们完全可以把绘制工作一次做完,然后保存成一张图到内存中。每次刷新我们只要调整这张图的起始坐标不就可以了吗?这样做,即便是计算量更大也无所谓,因为我只要绘制一次就OK,输出就是一张屏,效率非常稳定。这也正是我们在上一篇文章中提及的第二种方式的双缓冲。原理说清楚了,下面开始设计:

(1)调用刷新,如果内存图为空,则执行绘制;

(2)输出时,分上下两个部分。根据坐标变化,上半部分输出的是剩余的部分,下半部分输出的是超出屏幕的部分,这样就可以完美拼接了;

下面直接上代码:

        Bitmap bmpMem = null;
        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            if (bmpMem == null)
            {
                bmpMem = new Bitmap(panel1.Width, panel1.Height);
                Graphics g = Graphics.FromImage(bmpMem);

                int size = 5;
                //绘制小方格,并根据坐标变化实现上移滚动效果
                int xCount = panel1.Width / size + 1;
                int yCount = panel1.Height * 2 / size + 1;
                for (int i = 0; i < xCount; i++)
                {
                    for (int j = 0; j < yCount; j++)
                    {
                        int left = i * size * 2;
                        int top = j * size * 2 - start_top - size * 2;
                        Rectangle rectItem = new Rectangle(left, top, size, size);
                        g.FillRectangle(Brushes.AliceBlue, rectItem);
                    }
                }
                g.Dispose();
            }


            //黑色底清屏
            e.Graphics.Clear(Color.Black);

            //第一次输出fps
            //实际上这里是不需要的,但由于入门级的绘制太慢,如果不在绘制前输出,就看不到了
            e.Graphics.DrawString(string.Format("fps: {0}", (int)fps), Font, Brushes.Yellow, 10, 20);

            if (bmpMem != null)
            {
                int step = scroll_top % panel1.Height;
                Rectangle rectDestTop = new Rectangle(0, 0, panel1.Width, panel1.Height - step);
                Rectangle rectSrcTop = new Rectangle(0, step, panel1.Width, panel1.Height - step);
                e.Graphics.DrawImage(bmpMem, rectDestTop, rectSrcTop, GraphicsUnit.Pixel);

                Rectangle rectDestBottom = new Rectangle(0, panel1.Height - step, panel1.Width, step);
                Rectangle rectSrcBottom = new Rectangle(0, 0, panel1.Width, step);
                e.Graphics.DrawImage(bmpMem, rectDestBottom, rectSrcBottom, GraphicsUnit.Pixel);

                scroll_top++;
            }


            //计算fps
            calculateFPS();

            //第二次输出fps
            e.Graphics.DrawString(string.Format("fps: {0}", (int)fps), Font, Brushes.Yellow, 10, 20);
        }

效果看下图演示:

C#图形编程之GDI绘图:(三) 商用级之双缓冲

由于视频转Gif软件的限制,每帧最少要100ms,所以效果不是很明显,可以看到左上的fps达到了63帧左右。无论是放大还是更小的size,都能够保持稳定。细心的读者也许会发现,在两屏衔接的地方稍有瑕疵,因为这个不是本文要介绍的重点,就不展开了,喜欢钻研的读者可以思考下为什么,如何能够改进。

至此,C#图形编程之GDI绘图系列就讲完了。学会了这个,基本可以达到商用级了。

写在后面

美帝对我们进行了工业软件的封锁,工业软件会涉及到大量的图形化编程。C#做工控软件运行效率比Java高,界面开发比C++容易,笔者做过很多工控方面的项目都是用的C#。希望此文能够给有此方面兴趣的读者带来些许帮助,也祝福我们的国产工业软件早日踏上征途,领先世界。

记录工作和生活中的干货,感兴趣的朋友转发+关注。任何想法可在评论留言。

展开阅读全文

页面更新:2024-03-11

标签:图形   方格   坐标   界面   效率   内存   黑色   读者   两个   稳定   效果   方式   工业   工作   科技   软件

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top