cmapcube.c (4957B)
1 #include <u.h> 2 #include <libc.h> 3 #include <draw.h> 4 #include <event.h> 5 #include <geometry.h> 6 7 typedef struct Vert{ 8 Point3 world; 9 Point3 screen; 10 int color; 11 }Vert; 12 13 int nocubes; 14 int ncolor; 15 Quaternion q = {1.,0.,0.,0.}; 16 Image *image; 17 Image *bg; 18 Image *color[256]; 19 Rectangle viewrect; 20 int prevsel; 21 22 Point3 23 p3(double x, double y, double z, double w) 24 { 25 Point3 p; 26 27 p.x = x; 28 p.y = y; 29 p.z = z; 30 p.w = w; 31 return p; 32 } 33 34 int 35 cmp(Vert *a, Vert *b) 36 { 37 if(a->screen.z>b->screen.z) 38 return -1; 39 if(a->screen.z<b->screen.z) 40 return 1; 41 return 0; 42 } 43 44 /* crummy hack */ 45 void 46 readcolmap(Display *d, RGB *cmap) 47 { 48 int i, rgb, r, g, b; 49 50 for(i=0; i<256; i++){ 51 rgb = cmap2rgb(i); 52 r = rgb>>16; 53 g = (rgb>>8)&0xFF; 54 b = rgb & 0xFF; 55 cmap[i].red = r|(r<<8)|(r<<16)|(r<<24); 56 cmap[i].green = g|(g<<8)|(g<<16)|(g<<24); 57 cmap[i].blue = b|(b<<8)|(b<<16)|(b<<24); 58 } 59 } 60 61 void 62 colorspace(RGB *cmap, Vert *v) 63 { 64 Space *view; 65 int i; 66 67 for(i=0;i!=ncolor;i++){ 68 v[i].world.x=(cmap[i].red>>24)/255.-.5; 69 v[i].world.y=(cmap[i].green>>24)/255.-.5; 70 v[i].world.z=(cmap[i].blue>>24)/255.-.5; 71 v[i].world.w=1.; 72 v[i].color=i; 73 } 74 view = pushmat(0); 75 viewport(view, viewrect, 1.); 76 persp(view, 30., 3., 7.); 77 look(view, p3(0., 0., -5., 1.), p3(0., 0., 0., 1.), 78 p3(0., 1., 0., 1.)); 79 qrot(view, q); 80 for(i=0;i!=ncolor;i++) 81 v[i].screen = xformpointd(v[i].world, 0, view); 82 popmat(view); 83 } 84 85 void 86 line3(Vert a, Vert b) 87 { 88 line(image, Pt(a.screen.x, a.screen.y), Pt(b.screen.x, b.screen.y), 0, 0, 0, display->white, ZP); 89 } 90 91 92 void 93 redraw(void) 94 { 95 int i, m; 96 RGB cmap[256]; 97 Vert v[256]; 98 99 readcolmap(display, cmap); 100 colorspace(cmap, v); 101 draw(image, image->r, bg, nil, Pt(0, 0)); 102 m = Dx(viewrect)/2; 103 if(m > Dy(viewrect)/2) 104 m = Dy(viewrect)/2; 105 ellipse(image, addpt(viewrect.min, divpt(Pt(Dx(viewrect), Dy(viewrect)), 2)), 106 m, m, 1, display->white, ZP); 107 108 line3(v[0], v[0x36]); 109 line3(v[0x36], v[0x32]); 110 line3(v[0x32], v[0x3F]); 111 line3(v[0x3F], v[0]); 112 113 line3(v[0xF0], v[0xF3]); 114 line3(v[0xF3], v[0xFF]); 115 line3(v[0xFF], v[0xFC]); 116 line3(v[0xFC], v[0xF0]); 117 118 line3(v[0], v[0xF0]); 119 line3(v[0x36], v[0xF3]); 120 line3(v[0x32], v[0xFF]); 121 line3(v[0x3F], v[0xFC]); 122 123 qsort(v, ncolor, sizeof(Vert), (int(*)(const void*, const void*))cmp); 124 if(!nocubes) 125 for(i=0; i!=ncolor; i++) 126 draw(image, rectaddpt(Rect(-3, -3, 4, 4), Pt(v[i].screen.x, v[i].screen.y)), 127 color[v[i].color], nil, Pt(0, 0)); 128 draw(screen, image->r, image, nil, image->r.min); 129 flushimage(display, 1); 130 } 131 132 void 133 eresized(int new) 134 { 135 int dx, dy; 136 137 if(new && getwindow(display, Refnone) < 0){ 138 fprint(2, "colors: can't reattach to window: %r\n"); 139 exits("reshaped"); 140 } 141 draw(screen, screen->r, display->black, nil, ZP); 142 replclipr(screen, 0, insetrect(screen->r, 3)); 143 viewrect = screen->clipr; 144 viewrect.min.y += stringsize(font, "0i").y + 5; 145 if(image) 146 freeimage(image); 147 image = allocimage(display, viewrect, screen->chan, 0, DNofill); 148 dx = viewrect.max.x-viewrect.min.x; 149 dy = viewrect.max.y-viewrect.min.y; 150 if(dx>dy){ 151 viewrect.min.x=(viewrect.min.x+viewrect.max.x-dy)/2; 152 viewrect.max.x=viewrect.min.x+dy; 153 } 154 else{ 155 viewrect.min.y=(viewrect.min.y+viewrect.max.y-dx)/2; 156 viewrect.max.y=viewrect.min.y+dx; 157 } 158 if(image==nil){ 159 fprint(2, "can't allocate image\n"); 160 exits("bad allocimage"); 161 } 162 prevsel = -1; 163 redraw(); 164 } 165 166 void main(int argc, char **argv){ 167 Vert v[256]; 168 RGB cmap[256]; 169 char buf[100]; 170 Point p; 171 Mouse m; 172 int i; 173 ulong bgcol; 174 175 bgcol = DNofill; 176 ARGBEGIN{ 177 case 'n': 178 nocubes = 1; 179 break; 180 case 'b': 181 bgcol = DBlack; 182 break; 183 case 'w': 184 bgcol = DWhite; 185 break; 186 }ARGEND 187 188 if(initdraw(0,0,0) < 0) 189 sysfatal("initdraw: %r"); 190 ncolor=256; 191 for(i=0;i!=ncolor;i++) 192 color[i] = allocimage(display, Rect(0, 0, 1, 1), CMAP8, 1, cmap2rgba(i)); 193 if(bgcol==DNofill){ 194 bg = allocimage(display, Rect(0, 0, 2, 2), screen->chan, 1, DWhite); 195 draw(bg, Rect(0, 0, 1, 1), color[0], nil, Pt(0, 0)); 196 draw(bg, Rect(1, 1, 2, 2), color[0], nil, Pt(0, 0)); 197 }else 198 bg = allocimage(display, Rect(0,0,1,1), screen->chan, 1, bgcol); 199 200 einit(Emouse); 201 eresized(0); 202 203 for(;;){ 204 m = emouse(); 205 if(m.buttons&1) 206 qball(viewrect, &m, &q, redraw, 0); 207 else if(m.buttons & 2){ 208 readcolmap(display, cmap); 209 colorspace(cmap, v); 210 qsort(v, ncolor, sizeof(Vert), (int(*)(const void*, const void*))cmp); 211 while(m.buttons){ 212 for(i=ncolor-1; i!=0; i--){ 213 if(ptinrect(m.xy, rectaddpt(Rect(-3, -3, 4, 4), Pt(v[i].screen.x, v[i].screen.y)))){ 214 i = v[i].color; 215 if(i == prevsel) 216 break; 217 sprint(buf, "index %3d r %3ld g %3ld b %3ld", 218 i, 219 cmap[i].red>>24, 220 cmap[i].green>>24, 221 cmap[i].blue>>24); 222 p = addpt(screen->r.min, Pt(2,2)); 223 draw(screen, Rpt(p, addpt(p, stringsize(font, buf))), display->black, nil, p); 224 string(screen, p, display->white, ZP, font, buf); 225 prevsel = i; 226 break; 227 } 228 } 229 m = emouse(); 230 } 231 }else if(m.buttons&4){ 232 do 233 m = emouse(); 234 while(m.buttons); 235 exits(0); 236 } 237 } 238 }