2

我正在创建一个网络动画师(类似于 nam,如果您以前使用过它)。

基本上,我将节点表示为 GTK+ DrawingArea 上的小点,我更新这些节点的位置并在循环中重绘 DrawingArea。

生成的动画很快,但不流畅(有很多闪烁)。这可能是因为我在每一帧之前用纯色填充了 DrawingArea。

你认为我怎样才能最好地解决这个问题?我应该将帧预渲染到 Pixbuf 上吗?有更好的解决方案吗?

这是我当前的绘图代码(使用 PyGTK):

rect  = self.drawing_area.get_allocation()
style = self.drawing_area.get_style()

pos   = [n.position_at(self.t) for n in self.nodes]

self.drawing_area.window.draw_rectangle(style.bg_gc[gtk.STATE_NORMAL], True,
                                        0, 0, rect.width, rect.height)

for p in pos:
    self.drawing_area.window.draw_arc(style.fg_gc[gtk.STATE_NORMAL], True,
                                      rect.width  * (p.x / 2400.0) - NODE_SIZE/2,
                                      rect.height * (p.y / 2400.0) - NODE_SIZE/2,
                                      NODE_SIZE, NODE_SIZE,
                                      0, 64 * 360)

whereself.t是当前时间,在循环中递增。

4

2 回答 2

6

我更改了代码以将帧渲染到 Pixmap 上,并将 DrawingArea 替换为 Image。

虽然这解决了闪烁问题,但现在 CPU 使用率已达到峰值。动画还是挺快的,但我不认为这种方法是可扩展的。

我猜是时候进行一些优化了。

更新:事实证明,使用带有图像的暴露事件并不是一个好主意。CPU 使用率恢复正常。

于 2009-02-22T22:39:46.293 回答
3

关于暴露事件处理,请查看第一段动画与 Cairo + Gtk:P

Cairo 和 GTK+ 的多线程动画
cairo 和 GTK+ 的复杂动画可能会导致界面延迟。这是因为 gtk_main() 线程在单个循环中运行。所以,如果你的 do_draw() 函数实现了一个复杂的绘图命令,并且它是从 gtk_main() 线程调用的(比如通过 on_window_expose_event() 函数),你的 gtk 代码的其余部分将被阻塞,直到 do_draw() 函数完成. 因此,菜单项、鼠标单击甚至关闭按钮事件的处理速度都会很慢,并且您的界面会感觉迟钝。

一种解决方案是将所有处理器密集型绘图交给一个单独的线程,从而释放 gtk_main() 线程来响应事件。

http://cairographics.org/threaded_animation_with_cairo/

于 2011-04-14T14:48:14.373 回答