/* kanata8.c - Don Yang (uguu.org) 07/20/08 */ #include #include #include #include #include typedef int B; typedef double A; typedef void C; struct { A S, _, M, E, K, h, I, R, A, H, i; } a[512], *b; B c, d, e, f; A g, h[1024][3], i[1024][3], _, D, E, F, G, N, O, P, Q, MN, o, p, q, r, s, t, u, v, w, x, y, z, R, S, n, KA, NA, TA, k, l, m, L, M; GLfloat K[4][4] = { {1, 1, 1, 1}, {0, 1, -1, 0}, {0, -1, 1, 0}, {.9, .93, 1, .8} }; A H(A W) { return W * ((rand() & 32767) - 16384) / 16384.; } A I(A T, A U, A V, A W) { x = T + n * (U - T); y = U + n * (V - U); z = V + n * (W - V); R = x + n * (y - x); S = y + n * (z - y); return R + n * (S - R); } A J(A T, A U, A V, A W) { x = n * n; y = 1 - n; z = y * y; R = 2 * n * y; return 3 * (-z * T + (z - R) * U + (R - x) * V + x * W); } C xy(A X, A Y, A Z, A U, A V, A W) { k = Y * W - V * Z; l = U * Z - X * W; m = X * V - U * Y; } C xz() { glutPostRedisplay(); } C yx(B W, B V) { xz(); } C yz(unsigned char T, B U, B V) { glFlush(); exit(0); } C zx() { struct timeval T; gettimeofday(&T, NULL); g = T.tv_sec + T.tv_usec / 1000000.; } C zy() { zx(); if( g >= D ) { _ = D; D = g + 0.5 + (rand() & 32767) / 8192.; E = s; F = t; G = u; N = v; O = s + s - o; P = t + t - p; Q = u + u - q; MN = v + v - r; for(e = 0; e++ < 8;) { s = H(128); t = H(128); u = H(128); k = s - E; l = t - F; m = u - G; if( k * k + l * l + m * m > 1820 ) break; } for(e = 0; e++ < 8;) { o = s + 0.4 * H(128); p = t + 0.4 * H(128); q = u + 0.4 * H(128); k = o - s; l = p - t; m = q - u; if( k * k + l * l + m * m > 1820 ) break; } v = H(L); r = v + 0.4 * H(L); } for(n = (g - _) / (D - _); d - c && g - a[d].S >= 20; d = (d + 1) & 511); if( g - a[c].S >= 0.05 ) { c = (c + 1) & 511; a[c].S = g; } b = &a[c]; b->M = I(E, O, o, s); b->E = I(F, P, p, t); b->K = I(G, Q, q, u); b->h = J( E, O, o, s); b->I = J( F, P, p, t); b->R = J( G, Q, q, u); if( (w = b->h * b->h + b->I * b->I + b->R * b->R) > M ) { w = sqrt(w); b->h /= w; b->I /= w; b->R /= w; } xy(b->h, b->I, b->R, 0, 0, 1); b->A = 1; b->H = b->i = 0; if( (w = k * k + l * l + m * m) > M ) { w = sqrt(w); b->A = k / w; b->H = l / w; b->i = m / w; } k = b->h; l = b->I; m = b->R; x = sin(b->_ = I(N, MN, r, v)); y = cos(b->_); z = 1 - y; KA = k * l; NA = k * m; TA = l * m; R = b->A; S = b->H; w = b->i; b->A = (z * k * k + y) * R + (z * KA - m * x) * S + (z * NA + l * x) * w; b->H = (z * KA + m * x) * R + (z * l * l + y) * S + (z * TA - k * x) * w; b->i = (z * NA - l * x) * R + (z * TA + k * x) * S + (z * m * m + y) * w; h[e = c * 2][0] = a[c].M - 16 * a[c].A; h[e][1] = a[c].E - 16 * a[c].H; h[e][2] = a[c].K - 16 * a[c].i; h[f = e + 1][0] = a[c].M + 16 * a[c].A; h[f][1] = a[c].E + 16 * a[c].H; h[f][2] = a[c].K + 16 * a[c].i; xy(a[c].h, a[c].I, a[c].R, a[c].A, a[c].H, a[c].i); i[f][0] = i[e][0] = k; i[f][1] = i[e][1] = l; i[f][2] = i[e][2] = m; glDrawBuffer(GL_BACK); glClear(GL_COLOR_BUFFER_BIT); f = glutGet(GLUT_WINDOW_WIDTH); e = glutGet(GLUT_WINDOW_HEIGHT); k = l = 1; w = (f > e) ? (k = f / (A)e) : (l = e / (A)f); glViewport(0, 0, f, e); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-k, k, -l, l, 10, 12800); gluLookAt(0, 0, 1280, 0, 0, 0, 0, 1, 0); glLightfv(GL_LIGHT0, GL_DIFFUSE, *K); glLightfv(GL_LIGHT0, GL_SPECULAR, *K); glLightfv(GL_LIGHT0, GL_POSITION, K[1]); glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, K[2]); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, K[3]); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 4); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glVertexPointer(3, GL_DOUBLE, 0, h); glNormalPointer(GL_DOUBLE, 0, i); glBegin(GL_QUAD_STRIP); glColor4d(m = 0, 0, 0, 0); for(e = d; e != c; e = (e + 1) & 511) { glArrayElement(e * 2); glArrayElement(e * 2 + 1); if( m < 0.8 ) glColor4d(0.4, 0.5, 1, m += 0.08); } glEnd(); glutSwapBuffers(); glFlush(); } B main(B X, char **Y) { glutInit(&X, Y); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutSetWindow(glutCreateWindow("Kanata")); L = atan2(0, -1); M = 0.000001; glutDisplayFunc(zy); glutIdleFunc(xz); glutReshapeFunc(yx); glutKeyboardFunc(yz); glEnable(GL_BLEND); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_NORMALIZE); glShadeModel(GL_SMOOTH); glBlendFunc(GL_SRC_ALPHA, GL_ONE); zx(); srand((B)g); D = a[0].S = g - 1; o = H(128); p = H(128); q = H(128); r = H(L); s = t = u = N = c = d = 0; glutMainLoop(); return 0; }