/* gate2.c (ruriko.c) - Don Yang (uguu.org) Optimize pass 3 01/21/01 */ #ifdef _WIN32 #include #endif #include #include #include #include #define WINDOW_TITLE "Ruriko" #define WINDOW_WIDTH 640 #define WINDOW_HEIGHT 480 #define SCENE_SCALE 4 #define PERSP_SCALE 10 #define PERSP_NEAR 5 #define PERSP_FAR 9999 #define ANIMATE_PARAM_P 999 #define INIT_FRAME_LIMIT 3000 enum { OBJ_RING1, OBJ_RING2, OBJ_RING3, OBJ_PROJ0, OBJ_PROJ1, OBJ_PROJ2, OBJ_COUNT }; int i, j, FrameCount, FrameLimit, ACount, WindowHandle, State, Obj[OBJ_COUNT]; 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 = ANIMATE_PARAM_P / ((float)FrameCount); ProjectilePos = 1; } else if( State == 3 ) { if( FrameLimit == INIT_FRAME_LIMIT ) FrameLimit = FrameCount; FrameCount = 0; ProjectilePos = 0; theta0 = (rand() % 1024) * PI / 512; theta1 = (rand() % 1024) * PI / 512; phi0 = (rand() % 512) * PI / 1024 - PI / 8; phi1 = (rand() % 512) * PI / 1024 - PI / 8; radius = (rand() % 256) + 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 / -10; CameraTY = CameraSY / -10; CameraTZ = CameraSZ / -10 + ProjectilePos / 3; glutPostRedisplay(); } void CreateProjectile(int obj, float s1, float s2, float s3) { a0 = 0; glNewList(Obj[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[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 * PERSP_SCALE, a0 * PERSP_SCALE, -a1 * PERSP_SCALE, a1 * PERSP_SCALE, PERSP_NEAR, PERSP_FAR); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glScalef(SCENE_SCALE, SCENE_SCALE, SCENE_SCALE); 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(Obj[OBJ_RING1]); glCallList(Obj[OBJ_RING3]); glPopMatrix(); glRotatef(Angle, 0, 0, -1); glCallList(Obj[OBJ_RING2]); glPopMatrix(); if( ProjectilePos > 0 ) { glTranslatef(0, 0, ProjectilePos); glCallList(Obj[OBJ_PROJ0]); glCallList(Obj[(FrameCount & 1) ? OBJ_PROJ1 : OBJ_PROJ2]); } glutSwapBuffers(); glFlush(); } int main(int argc, char **argv) { glutInit(&argc, argv); srand(time(NULL)); PI = atan2(0, -1); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT); glutSetWindow(WindowHandle = glutCreateWindow(WINDOW_TITLE)); glutDisplayFunc(Render); glutKeyboardFunc(Keyboard); glutIdleFunc(Animate); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); t = nt = State = FrameCount = ACount = 0; FrameLimit = INIT_FRAME_LIMIT; Size = Angle = ProjectilePos = pdelta = 0; theta0 = theta1 = phi0 = phi1 = CameraSX = CameraSY = CameraTX = CameraTY = CameraTZ = 0; radius = CameraSZ = 200; CreateRing(OBJ_RING1, 60, 75, 2); CreateRing(OBJ_RING2, 100, 110, 3); CreateRing(OBJ_RING3, 155, 165, 8); CreateProjectile(OBJ_PROJ1, 20, 8, 28); CreateProjectile(OBJ_PROJ2, 18, 4, 30); glNewList(Obj[OBJ_PROJ0] = glGenLists(1), GL_COMPILE); glColor4d(0.5, 0.8, 0.9, 0.3); glutSolidSphere(26, 14, 7); glEndList(); glutMainLoop(); return 0; }