Windows对话框 - 如何加快绘画操作? [英] Windows dialog - how to speed up paint operation?

查看:45
本文介绍了Windows对话框 - 如何加快绘画操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好我在Visual Studio 2010中编写了一个2D RPG编辑器,在这里我有一个Map Properties对话框,它是在Map Properties的图标点击上显示的,但当我提起它时,paint操作需要一段时间而你在视觉上注意,任何想法如何加快油漆工艺代码的下面是油漆功能



MPMapPanel:

Hi there I am programming a 2D RPG Editor in Visual Studio 2010, where I have this Map Properties Dialog that is brought up on the icon click of Map Properties, but when I bring it up the paint operation takes a while and you notice it visually, any ideas how to speed up the paint process code is below for the paint function

MPMapPanel:

private void MPMapPanel_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            if (m_Map != null)
            {
                ArrayList mapLayers = m_Map.getMapLayers();

                for (int i = 0; i < mapLayers.Count; ++i)
                {
                    CLayer layer = (CLayer)mapLayers[i];
                    layer.DrawLayer(g);
                }
            }

            drawGrid(g);
        }

public void drawGrid(Graphics g)
        {
            if (m_bGrid)
            {
                int srcX = 0, srcY = 0;
                Pen pen = new Pen(Color.Black);
                for (int i = 0; i < m_Size.X; ++i)
                {
                    for (int j = 0; j < m_Size.Y; ++j)
                    {
                        srcX = i * 32;
                        srcY = j * 32;
                        g.DrawRectangle(pen, new Rectangle(srcX, srcY, 32, 32));
                    }
                }
            }
        }

CMap:
public ArrayList getMapLayers()
        {
            return m_MapLayers;
        }

CLayer:
public void DrawLayer(Graphics g)
        {
            ArrayList list = getSortedGraphicsList();
            for (int i = 0; i < list.Count; ++i)
            {
                CMapObject mapObj = (CMapObject)list[i];
                //if (mapObj != null)
                mapObj.Draw(g);
                //System.Console.WriteLine(mapObj.getResourceName() + mapObj.getZOrder());
            }
        }

public ArrayList getSortedGraphicsList()
        {
            ArrayList list = new ArrayList();
            //take from the grid tiles first
            for (int i = 0; i < this.m_MapObjects.Count; ++i)
            {
                ArrayList mapList = (ArrayList)m_MapObjects[i];
                for (int j = 0; j < mapList.Count; ++j)
                {
                    CGridObject gridObj = (CGridObject)mapList[j];
                    CMapObject MapGridObj = (CMapObject)gridObj.getMapObj();
                    if (MapGridObj != null)
                        list.Add(MapGridObj);
                }
            }

            for (int i = 0; i < this.m_ExtraObjects.Count; ++i)
            {
                CMapObject MapObj = (CMapObject)this.m_ExtraObjects[i];
                list.Add(MapObj);
            }

            //sort list
            list.Sort();
            return list;
        }

CMapObject:
public virtual void Draw(Graphics g)
        {
            m_Image.Draw(g);
        }


CImage:
public void Draw(Graphics g)
        {
            if (m_Image != null && m_bVisible)
            {
                Bitmap srcImage = getImage(m_rtSrcArea);
                g.DrawImage(srcImage, m_Location);
                srcImage.Dispose();
            }
        }

public Bitmap getImage(Rectangle rtArea)
        {
            Bitmap newImage = new Bitmap(rtArea.Width, rtArea.Height);
            Graphics g = Graphics.FromImage(newImage);
           
            g.DrawImage(m_Image, new Rectangle(0, 0, rtArea.Width, rtArea.Height), rtArea, GraphicsUnit.Pixel);
            return newImage;            
        }





另一个奇怪的事情是我有一个带有控件的主窗体使用相同的代码,但我没有油漆延迟。任何想法都会受到赞赏,因为它真的让我烦恼。



Another weird thing is I have a main form with a control on it that uses the same code, but I get no paint delay's. Any ideas would be appreciated, as it's really bugging me.

推荐答案

加速绘制它以预先绘制并缓存不会改变的东西的技巧,比如你的网格。然后,当您需要再次绘制网格时,只需将缓存的网格图像绘制到绘图表面上。完成!循环内没有循环。



您的代码也在每次绘制操作时泄漏资源。您创建笔,但在完成绘图时从不处理它们。更好的选择是在类级别创建一支笔,并在需要时重复使用它。在每次抽奖中都没有时间浪费时间反复创建相同颜色的笔。



当您的代码存在时,您仍然需要处理笔。



给出加速绘图速度幻觉的另一个技巧是创建一个与绘图表面大小相同的位图,并将所有绘图代码绘制到位图中。这称为后备缓冲。然后,当您完成在后备缓冲区上构图时,将整个后备缓冲区图像绘制到绘图表面。一切都显示在屏幕上。



当您创建后备缓冲区位图时,您还可以使用缓存图像绘制图像的背景,例如网格。当您创建后备缓冲区时,您将缓存的背景图像绘制到它,然后将所有动态对象绘制到它。
The trick to speeding up drawing it to predraw and cache the stuff that doesn't change, like your grid. Then, when you need to draw the grid again, you just paint the cached grid image onto your drawing surface. Done! No loops inside loops.

Your code is also leaking resources on every draw operation. You create Pens but never dispose them when you're done drawing. A better option is to create a single pen at the class level and reuse it whenever you need it. There's no time wasted creating the same color Pen over and over again on each draw.

When your code exists, you still have to Dispose the Pen.

Another trick to give the illusion of speeding up drawing is to create a Bitmap the size of your drawing surface and have all of your drawing code draw to the Bitmap instead. This is called a backbuffer. Then when your done composing the image on the backbuffer you paint the entire backbuffer image to the drawing surface. Everything shows up on screen all at once.

When you create your backbuffer Bitmap, you can also have a cached image that draws the background of your image, such as your grid. When you create the backbuffer, you paint the cached background image to it and then draw all of your dynamic objects to it.


这是我的绘图函数的新代码



This is my new code for my paint function

private void MPMapPanel_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            
            //create back buffer
            Bitmap backBuffer = new Bitmap(Width, Height);
            Graphics backG = Graphics.FromImage(backBuffer);
            
            if (m_Map != null)
            {
                ArrayList mapLayers = m_Map.getMapLayers();

                for (int i = 0; i < mapLayers.Count; ++i)
                {
                    CLayer layer = (CLayer)mapLayers[i];
                    layer.DrawLayer(backG);
                }
            }

            drawGrid(backG);

            g.DrawImage(backBuffer, new Point(0, 0));
        }


这篇关于Windows对话框 - 如何加快绘画操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆