#include #include #include uchar canvas[256*192]; Warp warp = {{{1 << 11, 0, 0}, {0, 1 << 11, 0}, {0, 0, 1 << 13}}, WFintupscale}; double sinθ = 0.0, cosθ = 1.0; double sdf(double x, double y, double z){ double t, d; t = x * cosθ - z * sinθ; d = sqrt(t * t + y * y) - 2.0; t = x * sinθ + z * cosθ; d = sqrt(d * d + t * t) - 0.2; t = -x; x = t * cosθ - z * sinθ; z = t * sinθ + z * cosθ; y += 0.5; t = sqrt(x * x + y * y) - 0.9; t = sqrt(t * t + z * z) - 0.2; if(t < d) d = t; y -= 0.5; t = x + 0.8; x = t * 0.923879532511 - y * 0.382683432365; y = t * 0.382683432365 + y * 0.923879532511; if(y > 1.5) y -= 1.5; else if(y > 0.0) y = 0.0; t = sqrt(x * x + y * y + z * z) - 0.2; return d < t ? d : t; } uchar march(double Δx, double Δy){ double t, d, z, x, y, Δz; Δz = 1.0 / sqrt(Δx * Δx + Δy * Δy + 27648.0); Δx *= Δz; Δy *= Δz; Δz *= 166.276877527; t = x = y = z = 0.0; do{ t += d = sdf(x, y, z - 5.0); x = t * Δx; y = t * Δy; z = t * Δz; }while(t < 8.0 && d > 0.05); if(t > 8.0) return 0; t = 255 - t * 35; return t < 0.0 ? 0 : t > 255.0 ? 255 : t; }; void main(int, char**){ Rectangle r; Image *rowimg, *img; int i, j, fc; vlong ns; if(initdraw(nil, nil, nil) < 0) sysfatal("initdraw: %r"); rowimg = allocimage(display, Rect(0, 0, 256 * 4, 1), GREY8, 1, DNofill); if(rowimg == nil) sysfatal("allocimage: %r"); img = allocimage(display, Rect(0, 0, 256, 192), GREY8, 0, DNofill); if(img == nil) sysfatal("allocimage: %r"); r.min.x = screen->r.min.x + screen->r.max.x - 4 * 256 >> 1; r.min.y = screen->r.min.y + screen->r.max.y - 4 * 192 >> 1; r.max.x = r.min.x + 4 * 256; r.max.y = r.min.y + 4 * 192; warp.m[0][2] = screen->r.min.x - r.min.x << 11; warp.m[1][2] = screen->r.min.y - r.min.y << 11; ns = uptime(); for(fc = 0; fc < 200; fc++){ for(j = 0; j < 192; j++) for(i = 0; i < 256; i++) canvas[j << 8 | i] = march(i - 128, j - 92); loadimage(img, img->r, canvas, sizeof canvas); affinewarp(screen, r, img, nil, ZP, &warp, 0); flushimage(display, 1); sinθ -= 0.1 * cosθ; cosθ += 0.1 * sinθ; } fprint(2, "affinewarp: %g frames per second\n", 200.0 / ((uptime() - ns) * 0.000000001)); ns = uptime(); for(fc = 0; fc < 200; fc++){ for(j = 0; j < 192; j++){ for(i = 0; i < 1024; i += 4) canvas[i] = canvas[i | 1] = canvas[i | 2] = canvas[i | 3] = march((i >> 2) - 128, j - 92); loadimage(rowimg, rowimg->r, canvas, 1024); r.max.y = r.min.y + 4; draw(screen, r, rowimg, nil, ZP); r.min.y = r.max.y; } r.min.y -= 192 * 4; flushimage(display, 1); sinθ -= 0.1 * cosθ; cosθ += 0.1 * sinθ; } fprint(2, "repl trick: %g frames per second\n", 200.0 / ((uptime() - ns) * 0.000000001)); exits(nil); }