commit df9e94f3ba048cdaac8a87d501313bfa1f529c0a
parent 0aff42a4711f0053dc26e7fd04a09ab7bb8b7435
Author: glenda <glenda@device>
Date: Mon, 31 Oct 2022 20:13:59 +0000
cubes: bit fiddling
Diffstat:
3 files changed, 216 insertions(+), 44 deletions(-)
diff --git a/src/cubes/cubes.c b/src/cubes/cubes.c
@@ -1,44 +1,94 @@
#include <u.h>
#include <libc.h>
#include <draw.h>
+#include <event.h>
#include <geometry.h>
#define OTSize (64 * 64 * 64)
-#define CSSize (640 * 480)
+
+#define QTSize (64 * 64)
+
+#define CSWidth 640
+#define CSHeight 640
+#define CSSize (CSWidth * CSHeight)
typedef struct Cube Cube;
+typedef struct Vect Vect;
struct Cube {
- Point3 min, Point3 max,
+ Point3 min; Point3 max;
};
struct Vect {
- Point3 pos, Point3 dir,
+ Point3 pos; Point3 dir;
+};
+
+typedef union Quad Quad;
+
+union Quad {
+ s32int p[4];
+ struct {
+ s32int tl;
+ s32int tr;
+ s32int bl;
+ s32int br;
+ };
};
u32int otree[OTSize];
u32int imgbuf[CSSize];
+Quad qtree[QTSize];
+
Cube cube;
Vect view;
void
+qtinit(void)
+{
+ s32int data[] = {
+ 0x00000001, 0x00000000, 0x00000000, 0x00000002,
+ 0x00000000, 0x00000002, 0x00000000, 0x00000002,
+ 0xffff0000, 0xff00ff00, 0xff0000ff, 0xff00ffff,
+ };
+ memcpy(qtree, data, sizeof(data));
+}
+
+s32int
+getqt(double X, double Y)
+{
+ unsigned int i = 0;
+ for (; i < sizeof(qtree);) {
+ Quad q = qtree[i];
+ s32int r = q.p[(X > 0) | ((Y > 0) << 1)];
+ if (r <= 0) return r;
+ double DX, DY;
+ DX = (X > 0) ? -1 : 1;
+ DY = (Y > 0) ? -1 : 1;
+
+ X = X * 2 + DX;
+ Y = Y * 2 + DY;
+ i = r;
+ }
+ return 0;
+}
+
+void
otinit(void)
{
int i, x,y,z;
double X,Y,Z;
- for (i = 0; i < OTSize; i++)
- for (y = 0; y < 64; y++)
- for (z = 0; z < 64; z++) {
+ for (i = 0; i < OTSize; i++) {
x = i % 64;
y = (i / 64) % 64;
- z = (i / 64 / 64) % 64;
- X = -1 + (double)x/32;
- Y = -1 + (double)y/32;
- Z = -1 + (double)z/32;
- if ( (X*X*X + Y*Y*Y + Z*Z*Z) < 1) {
- otree[i] = 0xffffffff;
+ z = i / 64 / 64;
+ X = -1 + (double)x / 32;
+ Y = -1 + (double)y / 32;
+ Z = -1 + (double)z / 32;
+
+ if ((X*X + Y*Y + Z*Z) < 1) {
+ otree[i] = 0xffff0000;
} else {
- otree[i] = 0;
+ otree[i] = 0x00000000;
}
}
}
@@ -47,22 +97,145 @@ void
initscene(void)
{
otinit();
+ qtinit();
cube = (Cube){
(Point3){-1, -1, -1, 1},
(Point3){ 1, 1, 1, 1},
-
};
+ view = (Vect){
+ (Point3){10, 20, 30, 1},
+ (Point3){0, 0, 0, 1},
+ };
+}
+
+int m[3][3];
+Point pts[3];
+Image *img;
+vlong n;
+char *s;
+
+void
+triangle(int i)
+{
+ int X = i % CSWidth;
+ int Y = i / CSWidth;
+
+ #define l(m) (m[0] * X + m[1] * Y + m[2])
+ #define istriag ((l(m[0]) > 0) && (l(m[1]) > 0) && (l(m[2]) > 0))
+ #define isline ((l(m[0]) <= 10) || (l(m[1]) <= 10) || (l(m[2]) <= 10))
+
+ imgbuf[i] = istriag ? 0x00ff7f00 : (imgbuf[i] / 2) &0xffff0000;
+
+
+ #undef l
+ #undef istriag
+ #undef isline
+}
+
+void
+vrender(void)
+{
+ int i;
+ for (i = 0; i < CSSize; i++) triangle(i);
+}
+
+void
+redraw(Image *)
+{
+ draw(screen, screen->r, display->white, nil, ZP);
+ draw(screen, screen->r, img, nil, ZP);
+
+ //Point dp = screen->r.min;
+
+ //line(screen, addpt(dp, pts[0]), addpt(dp, pts[1]), 0, 0, 0, display->white, ZP);
+ //line(screen, addpt(dp, pts[1]), addpt(dp, pts[2]), 0, 0, 0, display->white, ZP);
+ //line(screen, addpt(dp, pts[2]), addpt(dp, pts[0]), 0, 0, 0, display->white, ZP);
+
+ string(screen, screen->r.min, display->white, ZP, font, s);
+}
+
+void
+eresized(int new)
+{
+ if(new && getwindow(display, Refnone) < 0)
+ fprint(2,"can't reattach to window");
+ redraw(screen);
+}
+
+void
+randomize_pts(void)
+{
+ pts[0] = Pt(nrand(640), nrand(640));
+ pts[1] = Pt(nrand(640), nrand(640));
+ pts[2] = Pt(nrand(640), nrand(640));
+}
+
+void
+pts2linear(void)
+{
+#define lconv(m, u, w) \
+ m[0] = w.y - u.y, \
+ m[1] = u.x - w.x, \
+ m[2] = - m[0] * u.x - m[1] * u.y
+
+ lconv(m[0], pts[0], pts[1]);
+ lconv(m[1], pts[1], pts[2]);
+ lconv(m[2], pts[2], pts[0]);
+
+#undef lconv
}
void
+normalize(void)
+{
+#define l(m, u) (m[0] * u.x + m[1] * u.y + m[2])
+#define invert(m) m[0] = -m[0], m[1] = -m[1], m[2] = -m[2];
+
+ if (l(m[0], pts[2]) < 0) invert(m[0]);
+ if (l(m[1], pts[0]) < 0) invert(m[1]);
+ if (l(m[2], pts[1]) < 0) invert(m[2]);
+
+#undef l
+#undef invert
+}
+
+
+void
main(void)
{
- otinit();
- render();
+
+ srand(nsec());
+
+ initscene();
+ n = nsec();
+ vrender();
+ n = nsec() - n;
+ s = smprint("render time %lld nsec", n);
initdraw(nil, 0, "cubes");
- Image *i = allocimage(display, Rect(0, 0, 640, 480), RGBA32, 0, DRed);
- loadimage(i, i->r, (uchar *)imgbuf, CSSize * 4);
- draw(screen, screen->r, i, nil, ZP);
- flushimage(display, 1);
- for(;;);
+ img = allocimage(display, Rect(0, 0, CSWidth, CSHeight), XRGB32, 0, DRed);
+
+ randomize_pts();
+ pts2linear();
+ normalize();
+ n = nsec(); vrender(); n = nsec() - n;
+ loadimage(img, img->r, (uchar *)imgbuf, CSSize * 4);
+ s = smprint("render time %lld nsec", n);
+ redraw(img);
+
+ Event e;
+ einit(Emouse);
+ int timer = etimer(0, 125);
+ for(;;) {
+ int key = event(&e);
+ if (key == timer) {
+
+ randomize_pts();
+ pts2linear();
+ normalize();
+ n = nsec(); vrender(); n = nsec() - n;
+ loadimage(img, img->r, (uchar *)imgbuf, CSSize * 4);
+ free(s); s = smprint("render time %lld nsec", n);
+ redraw(img);
+ }
+ }
}
diff --git a/src/cubes/mkfile b/src/cubes/mkfile
@@ -4,3 +4,7 @@ TARG=cubes
OFILES=cubes.$O
</sys/src/cmd/mkone
+
+triangle: triangle.c
+ $CC triangle.c
+ $LD -o triangle triangle.$O
diff --git a/src/cubes/triangle.c b/src/cubes/triangle.c
@@ -5,37 +5,32 @@
#include <geometry.h>
#define CSWidth 640
-#define CSHeight 640
+#define CSHeight CSWidth
#define CSSize (CSWidth * CSHeight)
-u32int imgbuf[CSSize];
-int m[3][3];
+char imgbuf[CSSize];
Point pts[3];
+int m[3][3];
Image *img;
vlong n;
char *s;
void
-triangle(int i)
+vrender(void)
{
- int X = i % CSWidth;
- int Y = i / CSWidth;
-
- #define l(m) (m[0] * X + m[1] * Y + m[2])
- #define istriag ((l(m[0]) >= 0) && (l(m[1]) >= 0) && (l(m[2]) >= 0))
-
- imgbuf[i] = istriag ? 0x00ff7f00 : (imgbuf[i] / 2) & 0xffff0000;
+ int X, Y;
+ char *i = imgbuf;
+ for (X = 0; X < CSWidth; X++)
+ for (Y = 0; Y < CSHeight; Y++, i++) {
+ #define l(m) (m[0] * X + m[1] * Y + m[2])
+ #define istriag ((l(m[0]) >= 0) && (l(m[1]) >= 0) && (l(m[2]) >= 0))
- #undef l
- #undef istriag
-}
+ *i = istriag ? 0xff : 0x00;
-void
-vrender(void)
-{
- int i;
- for (i = 0; i < CSSize; i++) triangle(i);
+ #undef l
+ #undef istriag
+ }
}
void
@@ -58,9 +53,9 @@ eresized(int new)
void
randomize_pts(void)
{
- pts[0] = Pt(nrand(640), nrand(640));
- pts[1] = Pt(nrand(640), nrand(640));
- pts[2] = Pt(nrand(640), nrand(640));
+ pts[0] = Pt(nrand(CSWidth), nrand(CSWidth));
+ pts[1] = Pt(nrand(CSWidth), nrand(CSWidth));
+ pts[2] = Pt(nrand(CSWidth), nrand(CSWidth));
}
void
@@ -104,7 +99,7 @@ main(void)
n = nsec() - n;
s = smprint("render time %lld nsec", n);
initdraw(nil, 0, "cubes");
- img = allocimage(display, Rect(0, 0, CSWidth, CSHeight), XRGB32, 0, DRed);
+ img = allocimage(display, Rect(0, 0, CSWidth, CSHeight), CMAP8, 0, DRed);
randomize_pts();
pts2linear();