t3d color cube - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit ed01060152eba67eaa0f16605563c2de333d938d
 (DIR) parent cb003809883f69642b4b561671dc5539dae22e0a
 (HTM) Author: rsc <devnull@localhost>
       Date:   Tue,  4 Jan 2005 22:13:32 +0000
       
       3d color cube
       
       Diffstat:
         A src/cmd/draw/cmapcube.c             |     226 +++++++++++++++++++++++++++++++
       
       1 file changed, 226 insertions(+), 0 deletions(-)
       ---
 (DIR) diff --git a/src/cmd/draw/cmapcube.c b/src/cmd/draw/cmapcube.c
       t@@ -0,0 +1,226 @@
       +#include <u.h>
       +#include <libc.h>
       +#include <draw.h>
       +#include <event.h>
       +#include <geometry.h>
       +
       +typedef struct Vert{
       +        Point3 world;
       +        Point3 screen;
       +        int color;
       +}Vert;
       +
       +int                nocubes;
       +int                ncolor;
       +Quaternion        q;
       +Image                *image;
       +Image                *bg;
       +Image                *color[256];
       +Rectangle        viewrect;
       +int                prevsel;
       +
       +int
       +cmp(Vert *a, Vert *b)
       +{
       +        if(a->screen.z>b->screen.z)
       +                return -1;
       +        if(a->screen.z<b->screen.z)
       +                return 1;
       +        return 0;
       +}
       +
       +/* crummy hack */
       +void
       +readcolmap(Display *d, RGB *cmap)
       +{
       +        int i, rgb, r, g, b;
       +
       +        for(i=0; i<256; i++){
       +                rgb = cmap2rgb(i);
       +                r = rgb>>16;
       +                g = (rgb>>8)&0xFF;
       +                b = rgb & 0xFF;
       +                cmap[i].red = r|(r<<8)|(r<<16)|(r<<24);
       +                cmap[i].green = g|(g<<8)|(g<<16)|(g<<24);
       +                cmap[i].blue = b|(b<<8)|(b<<16)|(b<<24);
       +        }
       +}
       +
       +void
       +colorspace(RGB *cmap, Vert *v)
       +{
       +        Space *view;
       +        int i;
       +
       +        for(i=0;i!=ncolor;i++){
       +                v[i].world.x=(cmap[i].red>>24)/255.-.5;
       +                v[i].world.y=(cmap[i].green>>24)/255.-.5;
       +                v[i].world.z=(cmap[i].blue>>24)/255.-.5;
       +                v[i].world.w=1.;
       +                v[i].color=i;
       +        }
       +        view = pushmat(0);
       +        viewport(view, viewrect, 1.);
       +        persp(view, 30., 3., 7.);
       +        look(view, (Point3){0., 0., -5., 1.}, (Point3){0., 0., 0., 1.},
       +                (Point3){0., 1., 0., 1.});
       +        qrot(view, q);
       +        for(i=0;i!=ncolor;i++)
       +                v[i].screen = xformpointd(v[i].world, 0, view);
       +        popmat(view);
       +}
       +
       +void
       +line3(Vert a, Vert b)
       +{
       +        line(image, Pt(a.screen.x, a.screen.y), Pt(b.screen.x, b.screen.y), 0, 0, 0, display->white, ZP);
       +}
       +
       +
       +void
       +redraw(void)
       +{
       +        int i, m;
       +        RGB cmap[256];
       +        Vert v[256];
       +
       +        readcolmap(display, cmap);
       +        colorspace(cmap, v);
       +        draw(image, image->r, bg, nil, Pt(0, 0));
       +        m = Dx(viewrect)/2;
       +        if(m > Dy(viewrect)/2)
       +                m = Dy(viewrect)/2;
       +        ellipse(image, addpt(viewrect.min, divpt(Pt(Dx(viewrect), Dy(viewrect)), 2)),
       +                m, m, 1, display->white, ZP);
       +
       +        line3(v[0], v[0x36]);
       +        line3(v[0x36], v[0x32]);
       +        line3(v[0x32], v[0x3F]);
       +        line3(v[0x3F], v[0]);
       +        
       +        line3(v[0xF0], v[0xF3]);
       +        line3(v[0xF3], v[0xFF]);
       +        line3(v[0xFF], v[0xFC]);
       +        line3(v[0xFC], v[0xF0]);
       +
       +        line3(v[0], v[0xF0]);
       +        line3(v[0x36], v[0xF3]);
       +        line3(v[0x32], v[0xFF]);
       +        line3(v[0x3F], v[0xFC]);
       +
       +        qsort(v, ncolor, sizeof(Vert), (int(*)(const void*, const void*))cmp);
       +        if(!nocubes)
       +                for(i=0; i!=ncolor; i++)
       +                        draw(image, rectaddpt(Rect(-3, -3, 4, 4), Pt(v[i].screen.x, v[i].screen.y)),
       +                                color[v[i].color], nil, Pt(0, 0));
       +        draw(screen, image->r, image, nil, image->r.min);
       +        flushimage(display, 1);
       +}
       +
       +void
       +eresized(int new)
       +{
       +        int dx, dy;
       +
       +        if(new && getwindow(display, Refnone) < 0){
       +                fprint(2, "colors: can't reattach to window: %r\n");
       +                exits("reshaped");
       +        }
       +        draw(screen, screen->r, display->black, nil, ZP);
       +        replclipr(screen, 0, insetrect(screen->r, 3));
       +        viewrect = screen->clipr;
       +        viewrect.min.y += stringsize(font, "0i").y + 5;
       +        if(image)
       +                freeimage(image);
       +        image = allocimage(display, viewrect, screen->chan, 0, DNofill);
       +        dx = viewrect.max.x-viewrect.min.x;
       +        dy = viewrect.max.y-viewrect.min.y;
       +        if(dx>dy){
       +                viewrect.min.x=(viewrect.min.x+viewrect.max.x-dy)/2;
       +                viewrect.max.x=viewrect.min.x+dy;
       +        }
       +        else{
       +                viewrect.min.y=(viewrect.min.y+viewrect.max.y-dx)/2;
       +                viewrect.max.y=viewrect.min.y+dx;
       +        }
       +        if(image==nil){
       +                fprint(2, "can't allocate image\n");
       +                exits("bad allocimage");
       +        }
       +        prevsel = -1;
       +        redraw();
       +}
       +
       +void main(int argc, char **argv){
       +        Vert v[256];
       +        RGB cmap[256];
       +        char buf[100];
       +        Point p;
       +        Mouse m;
       +        int i;
       +        ulong bgcol;
       +
       +        bgcol = DNofill;
       +        ARGBEGIN{
       +        case 'n':
       +                nocubes = 1;
       +                break;
       +        case 'b':
       +                bgcol = DBlack;
       +                break;
       +        case 'w':
       +                bgcol = DWhite;
       +                break;
       +        }ARGEND
       +
       +        initdraw(0,0,0);
       +        ncolor=256;
       +        for(i=0;i!=ncolor;i++)
       +                color[i] = allocimage(display, Rect(0, 0, 1, 1), CMAP8, 1, cmap2rgba(i));
       +        if(bgcol==DNofill){
       +                bg = allocimage(display, Rect(0, 0, 2, 2), screen->chan, 1, DWhite);
       +                draw(bg, Rect(0, 0, 1, 1), color[0], nil, Pt(0, 0));
       +                draw(bg, Rect(1, 1, 2, 2), color[0], nil, Pt(0, 0));
       +        }else
       +                bg = allocimage(display, Rect(0,0,1,1), screen->chan, 1, bgcol);
       +
       +        q=(Quaternion){1.,0.,0.,0.};
       +        einit(Emouse);
       +        eresized(0);
       +
       +        for(;;){
       +                m = emouse();
       +                if(m.buttons&1)
       +                        qball(viewrect, &m, &q, redraw, 0);
       +                else if(m.buttons & 2){
       +                        readcolmap(display, cmap);
       +                        colorspace(cmap, v);
       +                        qsort(v, ncolor, sizeof(Vert), (int(*)(const void*, const void*))cmp);
       +                        while(m.buttons){
       +                                for(i=ncolor-1; i!=0; i--){
       +                                        if(ptinrect(m.xy, rectaddpt(Rect(-3, -3, 4, 4), Pt(v[i].screen.x, v[i].screen.y)))){
       +                                                i = v[i].color;
       +                                                if(i == prevsel)
       +                                                        break;
       +                                                sprint(buf, "index %3d r %3ld g %3ld b %3ld",
       +                                                        i,
       +                                                        cmap[i].red>>24,
       +                                                        cmap[i].green>>24,
       +                                                        cmap[i].blue>>24);
       +                                                p = addpt(screen->r.min, Pt(2,2));
       +                                                draw(screen, Rpt(p, addpt(p, stringsize(font, buf))), display->black, nil, p);
       +                                                string(screen, p, display->white, ZP, font, buf);
       +                                                prevsel = i;
       +                                                break;
       +                                        }
       +                                }
       +                                m = emouse();
       +                        }
       +                }else if(m.buttons&4){
       +                        do
       +                                m = emouse();
       +                        while(m.buttons);
       +                        exits(0);
       +                }
       +        }
       +}