3d color cube
This commit is contained in:
parent
cb00380988
commit
ed01060152
1 changed files with 226 additions and 0 deletions
226
src/cmd/draw/cmapcube.c
Normal file
226
src/cmd/draw/cmapcube.c
Normal file
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue