cube.c (2092B)
1 /* 2 * cube.c: a cube, rotating 3 */ 4 5 #include <u.h> 6 #include <libc.h> 7 #include <draw.h> 8 #include <geometry.h> 9 #include <thread.h> 10 #include <mouse.h> 11 #include <cursor.h> 12 #include <keyboard.h> 13 14 Image *red; 15 Space *s[4]; 16 double theta; 17 18 19 20 Point3 cube[8] = { 21 {-1, -1, -1, 1}, {-1, -1, 1, 1}, 22 {-1, 1, -1, 1}, {-1, 1, 1, 1}, 23 { 1, -1, -1, 1}, { 1, -1, 1, 1}, 24 { 1, 1, -1, 1}, { 1, 1, 1, 1}, 25 }; 26 27 int lines[12][2] = { 28 {0, 1}, {1, 3}, {3, 2}, // 0 1 3 2 29 {1, 5}, {5, 7}, {7, 3}, // 1 5 7 3 30 {5, 4}, {4, 6}, {6, 7}, // 5 4 6 7 31 {4, 0}, {0, 2}, {2, 6}, // 4 0 2 6 32 }; 33 34 void 35 mkmat(void) 36 { 37 s[0] = pushmat(nil); 38 s[1] = pushmat(s[0]); 39 s[2] = pushmat(s[1]); 40 s[3] = pushmat(s[2]); 41 rot(s[0], theta, 2); 42 look(s[1], 43 (Point3){5, 4, 3, 1}, 44 (Point3){0, 0, 0, 1}, 45 (Point3){0,0,1,1}); 46 persp(s[2], 30, 10, 25); 47 viewport(s[3], screen->r, 1); 48 } 49 50 Point3 51 tf(Point3 in, Space *s) 52 { 53 if (s == nil) return in; 54 return xformpointd(tf(in, s->next), nil, s); 55 } 56 57 void 58 drawscene(void) 59 { 60 int i; 61 Point3 s3, e3; 62 for (i = 0; i < 12; i++) { 63 s3 = tf(cube[lines[i][0]], s[3]); 64 e3 = tf(cube[lines[i][1]], s[3]); 65 line(screen, Pt(s3.x, s3.y), Pt(e3.x, e3.y), 0, 0, 1, red, ZP); 66 } 67 } 68 69 void 70 threadtimer(void *) 71 { 72 for(;;) { 73 sleep(1000 / 60); 74 theta += 2.5; 75 if (theta >= 90) theta -= 90; 76 ident(s[0]->t); 77 rot(s[0], theta, 2); 78 draw(screen, screen->r, display->black, nil, ZP); 79 drawscene(); 80 flushimage(display, 1); 81 } 82 } 83 84 void 85 threadmain(int, char **) 86 { 87 Mouse mv; 88 Rune kv; 89 int rv[2]; 90 91 initdraw(nil, nil, "cubes"); 92 Mousectl *mc = initmouse(nil, screen); 93 Keyboardctl *kc = initkeyboard(nil); 94 95 red = allocimage(display, Rect(0,0,1,1), CMAP8, 1, DRed); 96 97 mkmat(); 98 99 proccreate(threadtimer, nil, 64 * 1024); 100 101 Alt alts[5] = { 102 {kc->c, &kv, CHANRCV}, 103 {mc->c, &mv, CHANRCV}, 104 {mc->resizec, rv, CHANRCV}, 105 {0, 0, CHANEND}, 106 }; 107 for (;;) { 108 switch(alt(alts)){ 109 case 0: 110 if (kv == 0x7f) threadexitsall(nil); 111 break; 112 case 1: 113 break; 114 case 2: 115 if(getwindow(display, Refnone) < 0) 116 sysfatal("resize failed: %r"); 117 ident(s[3]->t); 118 viewport(s[3], screen->r, 1); 119 break; 120 } 121 } 122 }