/* gate3.c (ruriko.c) - Don Yang (uguu.org) Optimize pass 4 01/21/01 */ #ifdef _WIN32 #include #endif #include #include #include #include int i, j, FrameCount, FrameLimit, ACount, State, or1, or2, or3, op0, op1, op2, k1, k2, k3; float PI, Size, Angle, ProjectilePos, CameraSX, CameraSY, CameraSZ, CameraTX, CameraTY, CameraTZ, pdelta, theta0, theta1, phi0, phi1, radius, it, ip, r, a, a0, a1, c = CLOCKS_PER_SEC; clock_t t, nt; void Animate(void) { if( t == nt ) { t = clock(); nt = t + c; } Size = (State == 0) ? ((float)(clock() - t)) / c : (State == 3) ? ((float)(nt - clock())) / c : 1; if( Size > 1 ) Size = 1; if( Size < 0 ) Size = 0; if( clock() >= nt ) { t = clock(); nt = (t = clock()) + c; if( State == 1 ) { if( pdelta <= 0 ) pdelta = 999.0 / FrameCount; ProjectilePos = 1; } else if( State == 3 ) { if( FrameLimit == 3000 ) FrameLimit = FrameCount; FrameCount = 0; ProjectilePos = 0; theta0 = (rand() % k3) * PI / k2; theta1 = (rand() % k3) * PI / k2; phi0 = (rand() % k2) * PI / k3 - PI / 8; phi1 = (rand() % k2) * PI / k3 - PI / 8; radius = (rand() % k1) + 64; } State = (State + 1) % 4; } if( ProjectilePos > 0 ) ProjectilePos += pdelta; FrameCount++; Angle = (float)(ACount++ % 360); it = ((theta1 - theta0) * FrameCount) / FrameLimit + theta0; ip = ((phi1 - phi0) * FrameCount) / FrameLimit + phi0; CameraSY = radius * sin(ip); CameraSX = radius * cos(ip) * sin(it); CameraSZ = radius * cos(ip) * cos(it) + ProjectilePos / 2; CameraTX = CameraSX / -9; CameraTY = CameraSY / -9; CameraTZ = CameraSZ / -9 + ProjectilePos / 3; glutPostRedisplay(); } void CreateProjectile(int *obj, float s1, float s2, float s3) { a0 = 0; glNewList(*obj = glGenLists(1), GL_COMPILE); for(i = 0; i < 11; i++) { a1 = (PI * 2 * (i + 1)) / 11; glColor4d(1, 1, 1, 0.7); glVertex3d(0, 0, s3); glBegin(GL_TRIANGLE_STRIP); for(j = 0; j < 8; j++) { r = j / 7.0; r *= r; glColor4d(1 - r, 1 - 0.7 * r, 1 - 0.5 * r, 0.3); glVertex3d(s1 * j * cos(a0), s1 * j * sin(a0), s3 - s2 * j * j); glVertex3d(s1 * j * cos(a1), s1 * j * sin(a1), s3 - s2 * j * j); } glEnd(); a0 = a1; } glEndList(); } void CreateRing(int *obj, float r0, float r1, int count) { #define White() glColor4d(1.00, 1.00, 1.00, 1.00) #define Cyan() glColor4d(0.50, 1.00, 1.00, 0.90) #define Blue() glColor4d(0.12, 0.63, 0.81, 0.60) #define Vertex(x, y) \ r = (r1 - r0) * (y) + r0; \ a = (a1 - a0) * (x) + a0; \ glVertex3d(r * cos(a), r * sin(a), 0); #define Tri(c1, u1, v1, c2, u2, v2, c3, u3, v3) \ c1(); Vertex(u1, v1); \ c2(); Vertex(u2, v2); \ c3(); Vertex(u3, v3); #define TriM(c1, u1, v1, c2, u2, v2, c3, u3, v3) \ Tri(c1, u1, v1, c2, u2, v2, c3, u3, v3); \ Tri(c1, u1, (1-v1), c2, u2, (1-v2), c3, u3, (1-v3)); #define Quad(c1, u1, v1, c2, u2, v2, c3, u3, v3, c4, u4, v4) \ Tri(c1, u1, v1, c2, u2, v2, c3, u3, v3); \ c4(); Vertex(u4, v4); #define QuadM(c1, u1, v1, c2, u2, v2, c3, u3, v3, c4, u4, v4) \ Quad(c1, u1, v1, c2, u2, v2, c3, u3, v3, c4, u4, v4); \ Quad(c1, u1, (1-v1), c2, u2, (1-v2), c3, u3, (1-v3), c4, u4, (1-v4)); a0 = i = 0; glNewList(*obj = glGenLists(1), GL_COMPILE); for(; i < count; i++) { a1 = (float)((PI * 2 * (i + 1)) / count); glBegin(GL_QUADS); Quad ( Cyan, 0.00, 0.62, Cyan, 0.01, 0.62, Cyan, 0.01, 0.38, Cyan, 0.00, 0.38 ); QuadM ( Cyan, 0.00, 0.38, Cyan, 0.01, 0.38, Blue, 0.01, 0.00, Blue, 0.00, 0.16 ); Quad ( Cyan, 0.01, 0.38, Cyan, 0.01, 0.62, White, 0.02, 0.62, White, 0.02, 0.38 ); QuadM ( Cyan, 0.01, 0.38, White, 0.02, 0.38, White, 0.05, 0.00, Blue, 0.01, 0.00 ); Quad ( White, 0.02, 0.38, White, 0.02, 0.62, White, 0.05, 1.00, White, 0.05, 0.00 ); Quad ( White, 0.05, 0.00, White, 0.05, 1.00, White, 0.08, 1.00, White, 0.08, 0.00 ); Quad ( White, 0.08, 0.00, White, 0.08, 1.00, White, 0.14, 1.00, White, 0.14, 0.00 ); Quad ( White, 0.14, 0.00, White, 0.14, 1.00, White, 0.22, 0.62, White, 0.22, 0.38 ); QuadM ( Cyan, 0.22, 0.00, White, 0.22, 0.38, White, 0.30, 0.50, Cyan, 0.30, 0.38 ); QuadM ( Cyan, 0.30, 0.38, White, 0.30, 0.50, Cyan, 0.36, 0.50, Cyan, 0.36, 0.38 ); QuadM ( Blue, 0.30, 0.00, Cyan, 0.30, 0.38, Cyan, 0.36, 0.38, Blue, 0.36, 0.16 ); Quad ( Cyan, 0.36, 0.38, Cyan, 0.36, 0.62, Cyan, 0.40, 0.62, Cyan, 0.40, 0.38 ); QuadM ( Cyan, 0.36, 0.38, Cyan, 0.40, 0.38, Blue, 0.40, 0.16, Blue, 0.36, 0.16 ); QuadM ( Blue, 0.36, 0.16, Blue, 0.40, 0.16, Blue, 0.40, 0.00, Blue, 0.36, 0.00 ); for(j = 8; j < 20; j++) { QuadM ( Blue, (j / 20.0), 0.00, Blue, (j / 20.0), 0.16, Blue, ((j + 1) / 20.0), 0.16, Blue, ((j + 1) / 20.0), 0.00 ); QuadM ( Cyan, (j / 20.0), 0.38, Cyan, ((j + 1) / 20.0), 0.38, Blue, ((j + 1) / 20.0), 0.16, Blue, (j / 20.0), 0.16 ); Quad ( Cyan, (j / 20.0), 0.38, Cyan, (j / 20.0), 0.62, Cyan, ((j + 1) / 20.0), 0.62, Cyan, ((j + 1) / 20.0), 0.38 ); } glEnd(); glBegin(GL_TRIANGLES); TriM ( Blue, 0.00, 0.00, Blue, 0.00, 0.16, Blue, 0.01, 0.00 ); TriM ( White, 0.14, 0.00, White, 0.22, 0.38, Cyan, 0.22, 0.00 ); Tri ( White, 0.22, 0.38, White, 0.22, 0.62, White, 0.30, 0.50 ); TriM ( Cyan, 0.22, 0.00, Cyan, 0.30, 0.38, Blue, 0.30, 0.00 ); TriM ( Blue, 0.30, 0.00, Blue, 0.36, 0.16, Blue, 0.36, 0.00 ); glEnd(); a0 = a1; } glEndList(); } void Keyboard(unsigned char c, int u, int v) { glFinish(); exit(EXIT_SUCCESS); } void Render(void) { glDrawBuffer(GL_BACK); glClear(GL_COLOR_BUFFER_BIT); a0 = (float)glutGet(GLUT_WINDOW_WIDTH); a1 = (float)glutGet(GLUT_WINDOW_HEIGHT); if( i > j ) { a0 /= a1; a1 = 1; } else { a1 /= a0; a0 = 1; } glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-a0 * 9, a0 * 9, -a1 * 9, a1 * 9, 5, 9999); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glScalef(4, 4, 4); gluLookAt(CameraSX, CameraSY, CameraSZ, CameraTX, CameraTY, CameraTZ, 0, 1, 0); glPushMatrix(); glScalef(Size, Size, Size); glPushMatrix(); glRotatef(Angle, 0, 0, 1); glScalef(-1, 1, 1); glCallList(or1); glCallList(or3); glPopMatrix(); glRotatef(Angle, 0, 0, -1); glCallList(or2); glPopMatrix(); if( ProjectilePos > 0 ) { glTranslatef(0, 0, ProjectilePos); glCallList(op0); glCallList((FrameCount & 1) ? op1 : op2); } glutSwapBuffers(); glFlush(); } int main(int argc, char **argv) { glutInit(&argc, argv); srand(time(NULL)); PI = atan2(0, -1); k3 = 2 * (k2 = 2 * (k1 = 256)); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutInitWindowSize(640, 480); glutSetWindow(glutCreateWindow("Ruriko")); glutDisplayFunc(Render); glutKeyboardFunc(Keyboard); glutIdleFunc(Animate); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); t = nt = State = FrameCount = ACount = 0; FrameLimit = 3000; Size = Angle = ProjectilePos = pdelta = 0; theta0 = theta1 = phi0 = phi1 = CameraSX = CameraSY = CameraTX = CameraTY = CameraTZ = 0; radius = CameraSZ = k1; CreateRing(&or1, 60, 75, 2); CreateRing(&or2, 100, 110, 3); CreateRing(&or3, 155, 165, 8); CreateProjectile(&op1, 20, 8, 28); CreateProjectile(&op2, 18, 4, 30); glNewList(op0 = glGenLists(1), GL_COMPILE); glColor4d(0.5, 0.8, 0.9, 0.3); glutSolidSphere(26, 14, 7); glEndList(); glutMainLoop(); return 0; }