Rename GP_Context -> GP_Pixmap
[gfxprim.git] / demos / c_simple / koch.c
blobb5558c06f9abe8d0f52d439941917e5a7bc84169
1 /*****************************************************************************
2 * This file is part of gfxprim library. *
3 * *
4 * Gfxprim is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU Lesser General Public *
6 * License as published by the Free Software Foundation; either *
7 * version 2.1 of the License, or (at your option) any later version. *
8 * *
9 * Gfxprim is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
12 * Lesser General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU Lesser General Public *
15 * License along with gfxprim; if not, write to the Free Software *
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
17 * Boston, MA 02110-1301 USA *
18 * *
19 * Copyright (C) 2009-2010 Jiri "BlueBear" Dluhos *
20 * <jiri.bluebear.dluhos@gmail.com> *
21 * *
22 * Copyright (C) 2009-2013 Cyril Hrubis <metan@ucw.cz> *
23 * *
24 *****************************************************************************/
28 Simple test for triangle drawing runtime.
32 #include <math.h>
34 #include <GP.h>
36 #define TIMER_TICK 20000
37 #define DISPLAY_W 640
38 #define DISPLAY_H 480
39 #define sqr(x) ((x)*(x))
40 #define sgn(x) ((x)>0 ? 1 : -1)
42 static GP_Backend *backend;
43 static GP_Pixmap *pixmap;
45 static int iter, l, way = 1, draw_edge = 1;
46 static GP_Pixel black, blue, gray, red;
48 static void sierpinsky(double x1, double y1, double x4, double y4, int iter)
50 double x2, y2, x3, y3, x5, y5;
51 GP_Pixel pixel;
52 pixel = GP_RGBToPixel(0, 0, 255-16*iter, pixmap->pixel_type);
54 if (iter <= 0) {
55 if (draw_edge)
56 GP_Line(pixmap, x1, y1, x4, y4, black);
57 return;
60 x2 = floor((2*x1 + x4)/3);
61 y2 = floor((2*y1 + y4)/3);
63 x3 = floor((2*x4 + x1)/3);
64 y3 = floor((2*y4 + y1)/3);
66 x5 = (x1+x4)/2 + (y2 - y3)*sqrt(3.00/4);
67 y5 = (y1+y4)/2 + (x3 - x2)*sqrt(3.00/4);
69 GP_FillTriangle(pixmap, x2, y2, x3, y3, x5, y5, pixel);
71 GP_PutPixel(pixmap, x2, y2, red);
72 GP_PutPixel(pixmap, x3, y3, red);
73 GP_PutPixel(pixmap, x5, y5, red);
75 sierpinsky(x1, y1, x2, y2, iter - 1);
76 sierpinsky(x2, y2, x5, y5, iter - 1);
77 sierpinsky(x5, y5, x3, y3, iter - 1);
78 sierpinsky(x3, y3, x4, y4, iter - 1);
81 static void draw(int x, int y, int l, int iter)
83 double x1, y1, x2, y2, x3, y3;
84 int w = pixmap->w;
85 int h = pixmap->h;
87 l = ((w < h ? w : h) - 20)/(5 - 1.00*iter/120);
89 x1 = sin(1.00 * iter/57) * l + x;
90 y1 = cos(1.00 * iter/57) * l + y;
92 x2 = sin(1.00 * (iter+120)/57) * l + x;
93 y2 = cos(1.00 * (iter+120)/57) * l + y;
95 x3 = sin(1.00 * (iter+240)/57) * l + x;
96 y3 = cos(1.00 * (iter+240)/57) * l + y;
98 GP_Fill(pixmap, gray);
100 GP_FillTriangle(pixmap, x1, y1, x2, y2, x3, y3, blue);
102 sierpinsky(x1, y1, x2, y2, iter/60%6);
103 sierpinsky(x2, y2, x3, y3, iter/60%6);
104 sierpinsky(x3, y3, x1, y1, iter/60%6);
106 GP_BackendFlip(backend);
109 static int paused = 0;
111 void redraw(void)
113 if (paused)
114 return;
116 iter += 2 * way;
118 if (iter > 350)
119 way *= -1;
121 if (iter < 0)
122 way *= -1;
124 draw(pixmap->w/2, pixmap->h/2, l, iter);
127 int main(void)
129 const char *backend_opts = "X11";
131 backend = GP_BackendInit(backend_opts, "Koch");
133 if (backend == NULL) {
134 fprintf(stderr, "Failed to initalize backend '%s'\n",
135 backend_opts);
136 return 1;
139 pixmap = backend->pixmap;
141 black = GP_RGBToPixmapPixel(0x00, 0x00, 0x00, pixmap);
142 blue = GP_RGBToPixmapPixel(0x00, 0x00, 0xff, pixmap);
143 gray = GP_RGBToPixmapPixel(0xbe, 0xbe, 0xbe, pixmap);
144 red = GP_RGBToPixmapPixel(0xff, 0x00, 0x00, pixmap);
146 iter = 0;
147 draw(pixmap->w/2, pixmap->h/2, l, iter);
149 for (;;) {
150 GP_Event ev;
152 redraw();
154 GP_BackendPoll(backend);
156 while (GP_BackendGetEvent(backend, &ev)) {
157 GP_EventDump(&ev);
159 switch (ev.type) {
160 case GP_EV_KEY:
161 if (ev.code != GP_EV_KEY_DOWN)
162 continue;
164 switch (ev.val.key.key) {
165 case GP_KEY_P:
166 paused = !paused;
167 break;
168 case GP_KEY_E:
169 draw_edge = !draw_edge;
170 break;
171 case GP_KEY_ESC:
172 GP_BackendExit(backend);
173 return 0;
174 break;
176 break;
177 case GP_EV_SYS:
178 if (ev.code == GP_EV_SYS_RESIZE)
179 GP_BackendResizeAck(backend);
182 usleep(TIMER_TICK);
185 return 0;