Best Drawing approach
我在 wxWidgets 中开发了一个应用程序,我在其中使用位图进行绘图。所以当我的应用程序第一次启动时,它会从文件中读取坐标并相应地画线。该应用程序还从网络接收UDP数据包,UDP数据包还包含一些必须在屏幕上绘制的xy坐标信息,所以当接收到数据包时我重新绘制位图图像,并显示在屏幕上,我还需要刷新位图在鼠标移动事件上,因为在鼠标移动时,我必须在屏幕上绘制一些新的绘图。
所有这些都会增加运营成本并减慢我的 GUI。因此,请向我建议一些您认为在这种情况下可能有效的替代绘图方法。
我在谷歌上搜索并得到了OpenGL的选项,但由于时间紧迫我不想使用openGL,因为我没有任何OpenGL的经验。
- 你有 1337 分。我不喜欢那样。赞成:P
-
你不能在内存中保存一个位图实例,只向它绘制新信息,而不重绘整个东西吗?并将位图拉伸到屏幕...
-
@freerider,我正在绘制一些关于内存的特定信息,但是当我必须从位图中删除现有线条并绘制新线条时,在这种情况下我必须重新绘制整个位图。
-
@Siddiqui 你不能做一个位图缓存,其中包含多个时间点的线条图像。然后你只需要组合几个位图(只要使用 XOR,如果背景是白色的)并将剩余的线绘制到结果。
-
@freerider,假设我有一个主位图(GUI的背景)和一个与主位图异或的多边形,现在从网络接收到一个数据包,该数据包已经更新了多边形的坐标,那么如何在没有更新多边形的情况下更新多边形重绘主位图?
-
@Siddiqui 保存第一个多边形坐标,绘制多边形。获取更新后的坐标时,仅擦除位图中的第一个多边形,重新绘制新的多边形。换句话说:删除并仅绘制图像的所需部分......
-
@freerider,一旦我用主位图对多边形进行异或运算,我该如何擦除它?
-
@Siddiqui 将颜色设置为多边形所在的背景。
-
@freerider,它的彩色背景图像(不同的元素有不同的颜色表示)。
-
>一旦我用主位图对多边形进行异或运算,我该如何擦除它?再次异或! (让我感到困惑的是它在第一个 XOR 之后的样子,因为它是彩色的......)
-
让我直截了当地说:你有一个必须用鼠标绘制或从网络获取的形状填充的位图。一段时间后,必须重新绘制许多形状,这会使 GUI 陷入困境。您可以通过计算哪些形状不会改变并将它们绘制到第二个位图来优化,该位图用作新形状的新绘制的开始缓冲区?
-
@freerider,感谢您的宝贵建议。当然,这种方法会以某种方式有效,但是您能否建议我更多其他方法来更有效地实现这一目标?
-
只是游戏编程的一些基本经验法则:最大化数据的直通输出,搜索可以一次绘制多个形状的绘图函数。最小化运行时的计算:如果您可以为已绘制的形状提供多个缓存,请使用它。网上有很多有用的游戏开发教程。最后:使用另一个可以处理硬件加速并具有更好性能的 API。
听起来好像您的问题是您的 GUI 对用户输入没有响应,因为应用程序正忙于重绘显示。这类问题有几个通用解决方案。
使用工作线程在内存中绘制位图。在此过程中,主线程可以继续与用户交互。重新绘制位图后,工作线程向主线程发出信号,然后主线程将完成的位图复制到屏幕上 - 这非常快。
使用主线程将位图直接绘制到屏幕上,但在绘制代码中调用 wxApp::Yield()。这将允许 GUI 在漫长的绘图过程中保持对用户的响应。
选项 1 是"最好的",尤其是在多核机器上运行时,但要保持两个线程同步并防止它们之间的争用是一个挑战,除非您在多线程设计方面有丰富的经验。选项 2 更简单,但您仍需注意用户交互不会在第一个绘图过程完成之前开始另一个绘图过程。
- 这不会改变任何东西,"绘制记忆"是没有意义的(否则你会在哪里绘制?)。使用 2 个线程,一个用于绘图,一个用于执行代码并不是一个坏主意,但您必须将这两个线程连接在一起(即绘图时不计算,计算时不绘图,这意味着低收益)。 OP 想要一个简单(或不太复杂)的解决方案来解决他的问题,解决方案是"不要每帧更新 GUI,因为这需要时间"。喜欢与否:-)
保存要绘制的数据,而不是总是刷新位图,并让主循环不时刷新位图。
这样您就可以让程序永不停机。不利的一面当然是反应性会降低(即当数据到来时,它不会在屏幕上再显示 20 毫秒而不是立即显示)。