#include "raster.h" Keyboardctl *kbctl; Mousectl *mctl; int running; Matrix modelviewMat, projectionMat; Canvas *canvas; Texture *curtex; Image *img; Vector4 vertices[] = { { -0.5f, 0.5f, -0.5f, 1.0f }, { -0.5f, -0.5f, -0.5f, 1.0f }, { -0.5f, 0.5f, 0.5f, 1.0f }, { -0.5f, -0.5f, -0.5f, 1.0f }, { -0.5f, 0.5f, 0.5f, 1.0f }, { -0.5f, -0.5f, 0.5f, 1.0f }, { 0.5f, 0.5f, -0.5f, 1.0f }, { 0.5f, -0.5f, -0.5f, 1.0f }, { 0.5f, 0.5f, 0.5f, 1.0f }, { 0.5f, -0.5f, -0.5f, 1.0f }, { 0.5f, 0.5f, 0.5f, 1.0f }, { 0.5f, -0.5f, 0.5f, 1.0f }, }; Color colors[] = { { 0, 255, 0, 255 }, { 0, 0, 0, 255 }, { 0, 255, 255, 255 }, { 0, 0, 0, 255 }, { 0, 255, 255, 255 }, { 0, 0, 255, 255 }, { 255, 255, 0, 255 }, { 255, 0, 0, 255 }, { 255, 255, 255, 255 }, { 255, 0, 0, 255 }, { 255, 255, 255, 255 }, { 255, 0, 255, 255 }, }; Vector2 texcoords[] = { { 0.0f, 0.0f }, { 0.0f, 4.0f }, { 4.0f, 0.0f }, { 0.0f, 4.0f }, { 4.0f, 0.0f }, { 4.0f, 4.0f }, { 0.0f, 0.0f }, { 0.0f, 4.0f }, { 4.0f, 0.0f }, { 0.0f, 4.0f }, { 4.0f, 0.0f }, { 4.0f, 4.0f }, }; void drawCube(Canvas *canvas) { int i, j; Vertex p[3]; Matrix mat = mulmat(projectionMat, modelviewMat); for(i = 0; i < 4; i++){ for(j = 0; j < 3; j++){ Vector4 v = mulmatvec(mat, vertices[i*3+j]); v.x /= v.w; v.y /= v.w; v.z /= v.w; v.z = (-v.z+1.0f)/2.0f; p[j].v.x = canvas->w*(v.x+1)/2.0f; p[j].v.y = canvas->h*(-v.y+1)/2.0f; p[j].z = 16777216*v.z; p[j].oneoverz = 1.0f/v.w; p[j].c.r = colors[i*3+j].r << 14; p[j].c.g = colors[i*3+j].g << 14; p[j].c.b = colors[i*3+j].b << 14; p[j].c.a = colors[i*3+j].a << 14; p[j].st.s = texcoords[i*3+j].s*p[j].oneoverz; p[j].st.t = texcoords[i*3+j].t*p[j].oneoverz; } drawTriangle(canvas, p[0], p[1], p[2]); } } void drawwindow(Canvas *canvas) { doBlend = 0; clearcanvas(canvas); drawRect(canvas, (Point3){0,0,0}, (Point3){640, 480, 0}, (Color){128, 128, 128, 255}); doZ = 1; drawCube(canvas); doZ = 0; loadimage(img, Rect(0, 0, canvas->w, canvas->h), canvas->fb, canvas->w*canvas->h*4); draw(screen, screen->r, img, nil, ZP); flushimage(display, 1); } int pause = 0; void init(void) { u32int *p; canvas = makecanvas(640, 480); projectionMat = perspective(60, (float)640/480, 0.1f, 100.0f); modelviewMat = mulmat(translation(0.0f, 0.0f, -3.0f), rotationY(1.0f)); curtex = maketexture(2, 2); p = (u32*)curtex->pixels; p[0] = 0xFF000000; p[1] = 0xFFFFFFFF; p[2] = 0xFFFFFFFF; p[3] = 0xFF000000; img = allocimage(display, Rect(0, 0, canvas->w, canvas->h), RGBA32, 0, DRed); } void kbthread(void*) { Rune r; for(;;){ r = recvul(kbctl->c); switch(r){ case L'q': case Kdel: threadexitsall(nil); case L'p': pause = !pause; break; default: ; } } } void mthread(void*) { Mouse m; for(;;){ recv(mctl->c, &m); } } void resthread(void*) { for(;;){ recvul(mctl->resizec); if(getwindow(display, Refnone) < 0) sysfatal("resize failed: %r"); drawwindow(canvas); } } void resize(int x, int y) { int fd; fd = open("/dev/wctl", OWRITE); if(fd >= 0){ fprint(fd, "resize -dx %d -dy %d", x+8, y+8); close(fd); } } void threadmain(int /*argc*/, char */*argv*/[]) { newwindow(nil); resize(640, 480); if(initdraw(nil, nil, "raster") < 0) sysfatal("initdraw: %r"); kbctl = initkeyboard("/dev/cons"); if(kbctl == nil) sysfatal("initkeyboard: %r"); mctl = initmouse("/dev/mouse", screen); if(mctl == nil) sysfatal("initmouse: %r"); threadcreate(kbthread, nil, mainstacksize); threadcreate(mthread, nil, mainstacksize); threadcreate(resthread, nil, mainstacksize); init(); drawwindow(canvas); while(1){ if(!pause) modelviewMat = mulmat(modelviewMat, rotationY(0.005f)); drawwindow(canvas); yield(); } }