Question

I'm creating a network animator (similar to nam, if you have used it before).

Basically, I have nodes represented as small dots on a GTK+ DrawingArea, and I update the positions of these nodes and redraw the DrawingArea in a loop.

The resulting animation is fast, but not smooth (there's a lot of flicker). This is probably because I fill the DrawingArea with a solid color before each frame.

How do you think I can best tackle this problem? Should I pre-render the frames onto Pixbufs? Is there a better solution?

Here's my current drawing code (using 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)

where self.t is the current time, which is incremented in the loop.

Was it helpful?

Solution

I changed my code to render the frames onto a Pixmap, and replaced the DrawingArea with an Image.

While this solved the flickering, now the CPU usage has peaked. The animation is still quite fast, but I don't think this method is scalable.

Time for some optimization, I guess.

UPDATE: It turns out using expose-event with an Image wasn't such a good idea. CPU usage is back to normal.

OTHER TIPS

About the expose-event handling, check out the first paragraph on Animations with Cairo + Gtk:P

Multi-threaded Animation with Cairo and GTK+
Complex animations with cairo and GTK+ can result in a laggy interface. This is because the gtk_main() thread runs in a single loop. So, if your do_draw() function implements a complicated drawing command, and it is called from the gtk_main() thread (say by an on_window_expose_event() function), the rest of your gtk code will be blocked until the do_draw() function finishes. Consequentially, menu items, mouse clicks, and even close button events will be slow to be processed and your interface will feel laggy.

One solution is to hand off all the processor-intensive drawing to a separate thread, thus freeing the gtk_main() thread to respond to events.

http://cairographics.org/threaded_animation_with_cairo/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top