diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-03-06 22:14:42 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-03-06 22:16:08 +0000 |
commit | 3383a82eef11efe81f5318fe7da044918315cadb (patch) | |
tree | 8db04c1343341c2c5563558cfcbe563d84745e0c | |
parent | 1daf2991127355db8dbc4a112d2e55566c1f0ae3 (diff) |
Add sierpinski fractal triangle, lots of thin strokes
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | sierpinski-demo.c | 158 |
3 files changed, 162 insertions, 1 deletions
@@ -6,6 +6,7 @@ gears-demo gradient-demo poppler-demo pythagoras-demo +sierpinski-demo slideshow-demo spinner-demo spiral-demo @@ -38,7 +38,7 @@ else DEFINES+=-DHAVE_COGL=0 endif -all: spinner-demo spiral-demo slideshow-demo tiger-demo fish-demo flowers-demo gears-demo gradient-demo chart-demo waterfall-demo dragon-demo pythagoras-demo wave-demo +all: spinner-demo spiral-demo slideshow-demo tiger-demo fish-demo flowers-demo gears-demo gradient-demo chart-demo waterfall-demo dragon-demo pythagoras-demo wave-demo sierpinski-demo ifeq ($(shell pkg-config --exists poppler-glib && echo 1), 1) all: poppler-demo @@ -78,6 +78,8 @@ pythagoras-demo: pythagoras-demo.c $(SOURCES) demo.h Makefile $(CC) $(DEFINES) $(CFLAGS) -o $@ pythagoras-demo.c $(SOURCES) $(LIBS) wave-demo: wave-demo.c $(SOURCES) demo.h Makefile $(CC) $(DEFINES) $(CFLAGS) -o $@ wave-demo.c $(SOURCES) $(LIBS) +sierpinski-demo: sierpinski-demo.c $(SOURCES) demo.h Makefile + $(CC) $(DEFINES) $(CFLAGS) -o $@ sierpinski-demo.c $(SOURCES) $(LIBS) clean: rm -f *-demo diff --git a/sierpinski-demo.c b/sierpinski-demo.c new file mode 100644 index 0000000..5bd78a2 --- /dev/null +++ b/sierpinski-demo.c @@ -0,0 +1,158 @@ +#include "demo.h" +#include <string.h> +#include <sys/time.h> +#include <math.h> + +static const double m_1_sqrt_3 = 0.577359269; + +static void +T (cairo_t *cr, int size, int iterations) +{ + if (iterations-- == 0) + return; + + cairo_move_to (cr, 0, 0); + cairo_line_to (cr, size, 0); + cairo_line_to (cr, size/2, size*m_1_sqrt_3); + cairo_close_path (cr); + + size /= 2; + if (size >= 4) { + T (cr, size, iterations); + cairo_save (cr); { + cairo_translate (cr, size, 0); + T (cr, size, iterations); + } cairo_restore (cr); + cairo_save (cr); { + cairo_translate (cr, size/2, size*m_1_sqrt_3); + T (cr, size, iterations); + } cairo_restore (cr); + } +} + +static void +draw (cairo_t *cr, int width, int height, int iterations, double theta) +{ + cairo_set_source_rgb (cr, 1, 1, 1); + cairo_paint (cr); + + cairo_save (cr); + cairo_set_source_rgb (cr, 0, 0, 0); + cairo_set_line_width (cr, 1.); + + cairo_translate (cr, width/2, height/2); + cairo_rotate (cr, theta); + cairo_translate (cr, -width/2, -height/2); + + T (cr, width, iterations); + cairo_stroke (cr); + + cairo_restore (cr); +} + +static int done; +static void signal_handler(int sig) +{ + done = sig; +} + +int main (int argc, char **argv) +{ + struct device *device; + struct timeval start, last_tty, last_fps, now; + int iterations = 1, step = 1, tick = 10; + + double delta; + int frame = 0; + int frames = 0; + int show_fps = 1; + int benchmark; + const char *version; + enum clip clip; + double theta = 0; + + int n; + + device = device_open(argc, argv); + version = device_show_version(argc, argv); + clip = device_get_clip(argc, argv); + benchmark = device_get_benchmark(argc, argv); + if (benchmark == 0) + benchmark = 20; + if (benchmark > 0) + show_fps = 0; + + signal(SIGHUP, signal_handler); + + for (n = 1; n < argc; n++) { + if (strcmp (argv[n], "--hide-fps") == 0) + show_fps = 0; + } + + gettimeofday(&start, 0); now = last_tty = last_fps = start; + do { + struct framebuffer *fb = device->get_framebuffer (device); + cairo_t *cr = cairo_create(fb->surface); + + draw(cr, device->width, device->height, iterations, theta); + if (--tick == 0){ + iterations += step; + tick = 10; + if (iterations < 1) { + iterations = 1; + step = -step; + } else if (iterations > log2(device->width)) { + iterations = log(device->width); + step = -step; + } + } + theta += 0.1 / 180. * M_PI; + + gettimeofday(&now, NULL); + if (show_fps && last_fps.tv_sec) { + fps_draw(cr, device->name, version, &last_fps, &now); + } + last_fps = now; + + cairo_destroy(cr); + + fb->show (fb); + fb->destroy (fb); + + if (benchmark < 0 && 0) { + delta = now.tv_sec - last_tty.tv_sec; + delta += (now.tv_usec - last_tty.tv_usec)*1e-6; + frames++; + if (delta > 5) { + printf("%.2f fps\n", frames/delta); + last_tty = now; + frames = 0; + } + } + + frame++; + if (benchmark > 0) { + delta = now.tv_sec - start.tv_sec; + delta += (now.tv_usec - start.tv_usec)*1e-6; + if (delta > benchmark) { + printf("sierpinski: %.2f fps\n", frame / delta); + break; + } + } + } while (!done); + + if (benchmark < 0) { + struct framebuffer *fb = device->get_framebuffer (device); + cairo_t *cr = cairo_create(fb->surface); + + draw(cr, device->width, device->height, 2048, 0); + cairo_destroy(cr); + + fps_finish(fb, device->name, version); + fb->show (fb); + fb->destroy (fb); + pause(); + } + + return 0; +} |