/* koyomi9.c - Don Yang (uguu.org) 10/02/09 */ #include #include #include #include #include #define _(Ko, yo, mi) Ko ## yo ## mi #define G for #define F return #define C else typedef double K; typedef int j; typedef unsigned char E; typedef void l; K v, Q, f[1025][1025], s[7][3][8], _3[3] = {107, 192, 229}, L[3] = {240, 250, 250}, Z[3] = {0, 128, 64}, U = .40, V = .39, k, a, h, o, x, w; j n, J, m, A[9][4] = { {69, -27, 0, -1}, {75, -24, 3, -1}, {90, 21, 3, -1}, {93, 21, 0, -1}, {96, 24, 1, 0}, {93, 27, 0, 1}, {87, 27, -3, 1}, {72, -18, -3, 1}, {69, -21, 0, 1} }, M, O, R, I, S, H, i, T, q[] = { GL_TEXTURE_2D, GL_TEXTURE_GEN_S, GL_TEXTURE_GEN_T, GL_CULL_FACE, GL_DEPTH_TEST, GL_NORMALIZE, GL_S, GL_T, GL_TEXTURE_MAG_FILTER, GL_TEXTURE_MIN_FILTER, GL_LINEAR, GL_POLYGON, GL_RGB }; E D[512][512][3]; K z(K b, K o_, K B, K O_, K y) { F (O_ - B) * (y - b) / (o_ - b) + B; } j c(K y) { F ((M = (j)(512 * (y + 1))) < 0) ? 1024 - (1023 & -M) : M & 1023; } K p(K b, K B) { F z(0, RAND_MAX, b, B, rand()); } l u(j b, j B, K y) { if( !O || (b && b - 1024 && B && B - 1024) ) f[B][b] = y; } l e(j b, K B) { G(; b > 1; B /= 2) { b /= 2; G(I = 0; I < 1024; I = T) { T = (H = I + b) + b; G(R = 0; R < 1024; R = i) { i = (S = R + b) + b; u(S, H, (f[I][R] + f[I][i] + f[T][R] + f[T][i]) / 4); u(S, I, (f[I][R] + f[I][i] + f[H][S]) / 3); u(R, H, (f[I][R] + f[H][S] + f[T][R]) / 3); u(i, H, (f[I][i] + f[H][S] + f[T][i]) / 3); u(S, T, (f[H][S] + f[T][R] + f[T][i]) / 3); u(S, I, f[I][S] + p(-B, B)); u(R, H, f[H][R] + p(-B, B)); u(S, H, f[H][S] + p(-B, B)); u(i, H, f[H][i] + p(-B, B)); u(S, T, f[T][S] + p(-B, B)); } } } } l P(K *b, K *B, K y) { G(M = 0; M < 3; M++) D[I][R][M] = (E)z(0, 1, b[M], B[M], y); } l d(l) { if( x > U ) { P(L, _3, z(U, 1, 0, 1, x)); } C if( x > V ) { G(M = 0; M < 3; M++) D[I][R][M] = (E)L[M]; } C P(Z, L, z(-1, V, 0, 1, x)); } l N(l) { G(O = 0; O < 8; O++) s[M][0][O] = s[M][1][O] = s[M][2][O]; G(s[M][1][6] += p(2, 7); s[M][2][7] == s[M][0][7]; s[M][2][7] = (j)p(0, 4)); G(O = 0; O < 6; s[M][1][O++] = p(-360, 360)); O = (j)s[M][2][7]; s[M][1][O / 2] = ((O & 1) ? -360 : 360); } l t(l) { struct timeval b; gettimeofday(&b, NULL); v = b.tv_sec + b.tv_usec / 1e6; n++; } l X(l) { t(); glDrawBuffer(GL_BACK); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); R = glutGet(GLUT_WINDOW_WIDTH); I = glutGet(GLUT_WINDOW_HEIGHT); k = a = 1; if( R > I ) k = R / (K)I; C a = I / (K)R; glViewport(0, 0, R, I); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-k, k, -a, a, 30, 1e6); gluLookAt(0, 0, -1e4, 0, 0, 0, 0, -1, 0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); G(M = 0; M < 7; M++) { G(O = 0; O < 6; O++) s[M][2][O] = z(s[M][0][6], s[M][1][6], s[M][0][O], s[M][1][O], v); s[M][2][6] = v; if( v >= s[M][1][6] ) N(); glPushMatrix(); glTranslated(s[M][2][0], s[M][2][1], s[M][2][2]); G(O = 3; O < 6; O++) glRotated(s[M][2][O], (O - 3) ? 1 : 0, (O - 4) ? 1 : 0, (O - 5) ? 1 : 0); glCallList(J); glPopMatrix(); } glutSwapBuffers(); glFlush(); } l r(l) { glutPostRedisplay(); } l Y(j b, j I) { r(); } l W(E y, j b, j B) { glFlush(); if( (v -= Q) > 1 ) printf("%ffps\n", n / v); exit(0); } l g(j b) { glNormal3d(A[b][2] * cos(w), A[b][3], A[b][2] * sin(w)); glVertex3d(A[b][0] * cos(w), A[b][1], A[b][0] * sin(w)); } j main(j b, char **B) { glutInit(&b, B); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutSetWindow(glutCreateWindow("Koyomi")); glutDisplayFunc(X); glutIdleFunc(r); glutReshapeFunc(Y); glutKeyboardFunc(W); glShadeModel(GL_SMOOTH); t(); srand((j)v); J = glGenLists(1); glNewList(J, GL_COMPILE); k = atan2(0, -1) / 24; G(M = 0; M < 8; M++) { glBegin(GL_QUAD_STRIP); G(O = 0; O < 49;) { w = O++ * k; g(M); g(M + 1); } glEnd(); } glBegin(q[11]); G(M = 0; M < 48; g(0)) w = M++ * k; glEnd(); glBegin(q[11]); G(M = I = 0; M < 48; g(8)) w = M++ * -k; glEnd(); b = 1024; G(glEndList(); I <= b; I += 128) G(R = M = O = 0; R <= b; R += 128) f[I][R] = 0; G(; M < 32; M++) f[((j)p(0, 8)) * 128] [((j)p(0, 8)) * 128] = p(.1, .3); e(128, .06); G(M = 0; M <= b; M++) { f[b][M] = f[0][M]; f[M][b] = f[M][0]; } O = 1; e(b, .48); G(I = 0; I < b; I++) G(R = 0; R < b; f[I][R++] *= 255); b /= 2; G(I = 0; I < b; I++) { a = z(0, 511, 1, -1, I); G(R = 0; R < b; R++) { k = z(0, 511, -1, 1, R); h = k * k + a * a; o = sqrt((1 - k * k) / 2); if( a >= o ) { x = 1; d(); } C if( a <= -o ) { x = -1; d(); } C if( h < 1 ) { x = a / sqrt(1 - h); if( x >= -1 && x <= 1 ) d(); } if( h < 1 ) if( (w = f[c(k / sqrt(1 - h))] [c(a / sqrt(1 - h))]) > 0 ) G(M = 0; M < 3; M++) D[I][R][M] = (E)((O = (j)D[I][R][M] + (j)w) > 255 ? 255 : O); } } glGenTextures(1, &m); glBindTexture(*q, m); G(M = 0; M < 6; glEnable(q[M++])); G(glTexImage2D(*q, 0, q[12], b, b, 0, q[12], GL_UNSIGNED_BYTE, D); M < 8; glTexGeni(q[M++], GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP)); G(glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); M < 10; glTexParameteri(*q, q[M++], q[10])); Q = v; G(M = n = 0; M < 7; M++) { G(O = 0; O < 6; s[M][2][O++] = p(-360, 360)); s[M][2][7] = s[M][2][6] = v; N(); } glutMainLoop(); F 0; }