4

我目前在Windows 窗体应用程序中工作,并且正在制作本质上将成为游戏地图编辑器的东西。我解决这个问题的方法是有一个中央TabControl,每个都TabPage包含一个自定义控件PictureBox,所有其他 UI 控件都围绕这​​个中央TabControl。使用PictureBox它的 Paint 事件来绘制放置在地图上的所有内容,因此将多个大小、旋转和比例等的图像绘制到单个PictureBox. 到目前为止,这一切进展顺利。TabPage本质上用作 的视图窗口,PictureBox大小为 (1280x720)。

问题在于地图的制作比例。屏幕上的平均(也是最大)地图大小约为19200x10800 像素,并且可以在任何一点由数百个项目组成。当仅绘制大小为19200x10800 像素的背景图像PictureBox时,当它重新绘制时开始闪烁并使程序无法使用。由于地图太大,您可以在它们周围平移,这就是闪烁真正显示的地方。此外,为了文件大小,我不想使用19200x10800px图像源,并且缩放图像质量根本不是问题。

我已经阅读了大量关于为什么会这样的阅读,并且感觉到目前为止我已经尝试了一切。到目前为止,我尝试过:

  • 背景图像只有 1920x1080 并将其放大 10 倍
  • 从 1920x1080 图像开始,以编程方式调整其大小并绘制此图像
  • 将背景分割成多个部分(我尝试了许多不同的数量)并仅绘制视图窗口可以看到的部分(尝试了小(1080p)和大(10800p)图像)
  • 使用图形剪辑,以便只绘制屏幕上的东西
  • 在图片框和图片框所在的窗体上都使用了双缓冲
  • 将初始化时的图像转换为具有更快格式的“优化位图”,然后绘制位图

我可能已经尝试了其他一些事情以及一些小的优化,但是我花了很长时间才忘记了其余的事情。从我读过的内容来看,由于某种性能原因或图片框的限制,它最有可能与控件重绘速度过慢有关,但是由于缺乏表单应用程序控件的经验,我无法确切知道发生了什么。

目前要在Paint事件中绘制背景我有:

g.DrawImage(image, new Rectangle(0, 0, (int)(image.Size.Width * levelScale), (int)(image.Size.Height * levelScale)));

或者

g.ScaleTransform(levelScale, levelScale);
g.DrawImage(image, new Rectangle(0, 0, (int)(image.Size.Width), (int)(image.Size.Height)));

其中 g 是Graphics对象。

我是否达到了 Win 表单应用程序功能的限制,或者我可能缺少什么?

任何和所有帮助表示赞赏,

提前致谢。

4

3 回答 3

4

只是为了形式,我会回答我自己的问题,以防万一其他人想知道结果。

基于压倒性的共识,即 winforms 只是没有做我试图用它做的事情,我决定我必须转移到其他平台。向我建议的是 WPF、DirectX 和 OpenGL,但经过广泛搜索后,我发现我认为是最佳解决方案。

为了利用 DirectX 硬件加速的强大功能,MS 使您可以将 XNA 图形设备嵌入到 winforms 应用程序中。本质上,您可以创建以正常 winform 样式运行的自定义控件,这些控件可以访问更高水平的图形控件。以这种方式(需要做一些额外的工作),我已经用一个处理所有绘图的自定义图形控件替换了我正在使用的图片框。这工作得很好,而且从好的方面来说,我不必对我的开发时间造成太大的影响。

对于那些寻找更多信息的人,请参阅这个问题,其中包含应该有帮助的更多链接。再次感谢所有给予建议的人!

于 2013-07-04T09:03:52.173 回答
1

这是来自底部 URL 的引用答案。底部的链接中有代码示例。希望这会有所帮助;不确定你是否尝试过这个,也许它会帮助你从现有的图片框控件中获得更多的汁液。正如其他答案中所解释的那样,听起来您将在不久的将来被迫采用更强大的解决方案(DirectX/OpenGL 或 WPF)

** 部分引用来自http://social.msdn.microsoft.com/Forums/en-US/68ecd1f6-2eeb-45ce-a881-24c62145ab0e/c-picturebox-problems

“我猜真正的问题是重绘图像需要很长时间。GDI+ 非常慢,它不使用任何视频硬件加速。要加快速度,请务必避免重新缩放绘图并使用Format32PArgb 格式。它比任何其他格式快大约 10 倍。首先将图像加载到正确格式的位图中。

于 2013-07-04T03:51:40.633 回答
0

如果您有很多项目(可能实现为控件),请忘记 Windows 窗体的标准事件机制。前段时间,我编写了一个逻辑门编辑器/模拟器,它在编辑器中支持成千上万个门,而且速度非常快。在那里,我使用了画布并将门绘制为自定义“图像”,而不是将它们作为控件。您必须编写一个自定义GetUnderlyingGate函数,从坐标数组中解析当前的门/瓷砖(您的编辑器是瓷砖地图编辑器吗?)。此外,还有一些可见的区域优化。

也许,当我回到家时,我会上传一些源代码并通知你。

于 2013-07-03T10:40:19.693 回答