/* gate.c (ruriko.c) - Don Yang (uguu.org) lclint 2.5m: 173 errors -paramuse -predboolint -realcompare -type 01/21/01 */ #ifdef _WIN32 #include #endif #include #include #include #include #include #define WINDOW_TITLE "Ruriko" #define WINDOW_WIDTH 640 #define WINDOW_HEIGHT 480 #define WINDOW_POS_X 32 #define WINDOW_POS_Y 32 #define SCENE_SCALE 4 #define PERSP_SCALE 10 #define PERSP_NEAR 5 #define PERSP_FAR 20000 #define ANIMATE_PARAM1 1 #define ANIMATE_PARAM2 1 #define ANIMATE_PARAM3 1 #define ANIMATE_PARAM4 1 #define ANIMATE_PARAM_P 1000 #define INIT_FRAME_LIMIT 3000 enum { OBJ_RING1, OBJ_RING2, OBJ_RING3, OBJ_PROJ0, OBJ_PROJ1, OBJ_PROJ2, OBJ_COUNT, STATE_OPEN, STATE_HOLD, STATE_FIRE, STATE_CLOSE }; static double PI; static int FrameCount, FrameLimit; static int WindowHandle; static GLuint Obj[OBJ_COUNT]; static int State; static GLfloat Size, Angle; static GLfloat ProjectilePos; static GLdouble CameraSX, CameraSY, CameraSZ; static GLdouble CameraTX, CameraTY, CameraTZ; static void Animate(void); static void CreateObj(void); static void CreateProjectile(int obj, double s1, double s2, double s3); static void CreateRing(int obj, double r1, double r2, int count); static void DestroyObj(void); static void InitDisplay(void); static void Keyboard(unsigned char c, int u, int v); static void Render(void); /******************************************************************** main */ int main(int argc, char **argv) { glutInit(&argc, argv); srand(time(NULL)); PI = atan2(0, -1); InitDisplay(); CreateObj(); glutMainLoop(); return 0; } /* main() */ /***************************************************************** Animate */ static void Animate(void) { static double theta0, theta1, phi0, phi1, radius, it, ip; static GLfloat pdelta = 0; static clock_t t = 0, nt = 0; if( (t == nt) && (nt == 0) ) { t = clock(); nt = t + ANIMATE_PARAM1 * CLOCKS_PER_SEC; theta0 = ((rand() % 1024) * PI) / 512.0; theta1 = ((rand() % 1024) * PI) / 512.0; phi0 = ((rand() % 512) * PI) / 1024.0 - PI / 8; phi1 = ((rand() % 512) * PI) / 1024.0 - PI / 8; radius = (rand() % 256) + 64; } if( State == STATE_OPEN ) { Size = ((GLfloat)(clock() - t) * ANIMATE_PARAM1) / CLOCKS_PER_SEC; } else if( State == STATE_CLOSE ) { Size = ((GLfloat)(nt - clock()) * ANIMATE_PARAM4) / CLOCKS_PER_SEC; } else { Size = 1; } if( Size > 1 ) Size = 1; if( Size < 0 ) Size = 0; if( clock() >= nt ) { t = clock(); switch( State ) { case STATE_OPEN: nt = t + ANIMATE_PARAM2 * CLOCKS_PER_SEC; break; case STATE_HOLD: if( pdelta <= 0 ) pdelta = ANIMATE_PARAM_P / ((GLfloat)FrameCount); nt = t + ANIMATE_PARAM3 * CLOCKS_PER_SEC; ProjectilePos = 0; break; case STATE_FIRE: nt = t + ANIMATE_PARAM4 * CLOCKS_PER_SEC; break; default: /* STATE_CLOSE */ nt = t + ANIMATE_PARAM1 * CLOCKS_PER_SEC; if( FrameLimit == INIT_FRAME_LIMIT ) FrameLimit = FrameCount; FrameCount = 0; ProjectilePos = -1; theta0 = ((rand() % 1024) * PI) / 512.0; theta1 = ((rand() % 1024) * PI) / 512.0; phi0 = ((rand() % 512) * PI) / 1024.0 - PI / 8; phi1 = ((rand() % 512) * PI) / 1024.0 - PI / 8; radius = (rand() % 256) + 64; break; } if( ++State > STATE_CLOSE ) State = STATE_OPEN; } if( ProjectilePos >= 0 ) ProjectilePos += pdelta; Angle = (GLfloat)(FrameCount++ % 360); it = ((theta1 - theta0) * FrameCount) / FrameLimit + theta0; ip = ((phi1 - phi0) * FrameCount) / FrameLimit + phi0; CameraSY = radius * sin(ip); CameraSX = radius * cos(ip) * cos(it); CameraSZ = radius * cos(ip) * sin(it) + ProjectilePos / 2; CameraTX = CameraSX / -10; CameraTY = CameraSY / -10; CameraTZ = CameraSZ / -10 + ProjectilePos / 3; glutPostRedisplay(); } /* Animate() */ /*************************************************************** CreateObj */ static void CreateObj(void) { 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, 8, 4); glEndList(); } /* CreateObj() */ /******************************************************** CreateProjectile */ static void CreateProjectile(int obj, double s1, double s2, double s3) { double a0, a1, r; int i, j; a0 = 0; glNewList(Obj[obj] = glGenLists(1), GL_COMPILE); for(i = 0; i < 8; i++) { a1 = (PI * 2 * (i + 1)) / 8; 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(); } /* CreateProjectile() */ /************************************************************** CreateRing */ static void CreateRing(int obj, double r0, double r1, int count) { const double x1 = 0.01, x2 = 0.02, x3 = 0.05, xe = 0.08; const double x4 = 0.14, x5 = 0.22, x6 = 0.30, x7 = 0.36; const double y1 = 0.16, y2 = 0.38, y3 = 0.62, y4 = 0.84; double r, a, a0, a1; int i, j; #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); a0 = 0; glNewList(Obj[obj] = glGenLists(1), GL_COMPILE); for(i = 0; i < count; i++) { a1 = (double)((PI * 2 * (i + 1)) / count); glBegin(GL_QUADS); Blue(); Vertex(0., y4); Vertex(x1, 1.); Cyan(); Vertex(x1, y3); Vertex(0., y3); Vertex(0., y3); Vertex(x1, y3); Vertex(x1, y2); Vertex(0., y2); Vertex(0., y2); Vertex(x1, y2); Blue(); Vertex(x1, 0.); Vertex(0., y1); Vertex(x1, 1.); White(); Vertex(x3, 1.); Vertex(x2, y3); Cyan(); Vertex(x1, y3); Vertex(x1, y3); White(); Vertex(x2, y3); Vertex(x2, y2); Cyan(); Vertex(x1, y2); Vertex(x1, y2); White(); Vertex(x2, y2); Vertex(x3, 0.); Blue(); Vertex(x1, 0.); White(); Vertex(x3, 1.); Vertex(x3, 0.); Vertex(x2, y2); Vertex(x2, y3); Vertex(x3, 1.); Vertex(xe, 1.); Vertex(xe, 0.); Vertex(x3, 0.); Vertex(xe, 1.); Vertex(x4, 1.); Vertex(x4, 0.); Vertex(xe, 0.); Vertex(x4, 1.); Vertex(x5, y3); Vertex(x5, y2); Vertex(x4, 0.); Cyan(); Vertex(x5, 1.); Vertex(x6, y3); White(); Vertex(x6, .5); Vertex(x5, y3); Vertex(x5, y2); Vertex(x6, .5); Cyan(); Vertex(x6, y2); Vertex(x5, 0.); Blue(); Vertex(x6, 1.); Vertex(x7, y4); Cyan(); Vertex(x7, y3); Vertex(x6, y3); Vertex(x6, y3); Vertex(x7, y3); Vertex(x7, y2); Vertex(x6, y2); Vertex(x6, y2); Vertex(x7, y2); Blue(); Vertex(x7, y1); Vertex(x6, 0.); Vertex(x7, 1.); Vertex(.4, 1.); Vertex(.4, y4); Vertex(x7, y4); Vertex(x7, y4); Vertex(.4, y4); Cyan(); Vertex(.4, y3); Vertex(x7, y3); Vertex(x7, y3); Vertex(.4, y3); Vertex(.4, y2); Vertex(x7, y2); Vertex(x7, y2); Vertex(.4, y2); Blue(); Vertex(.4, y1); Vertex(x7, y1); Vertex(x7, y1); Vertex(.4, y1); Vertex(.4, 0.); Vertex(x7, 0.); for(j = 8; j < 20; j++) { Blue(); Vertex(j / 20.0, 1.); Vertex((j + 1) / 20.0, 1.); Vertex((j + 1) / 20.0, y4); Vertex(j / 20.0, y4); Vertex(j / 20.0, y4); Vertex((j + 1) / 20.0, y4); Cyan(); Vertex((j + 1) / 20.0, y3); Vertex(j / 20.0, y3); Vertex(j / 20.0, y3); Vertex((j + 1) / 20.0, y3); Vertex((j + 1) / 20.0, y2); Vertex(j / 20.0, y2); Vertex(j / 20.0, y2); Vertex((j + 1) / 20.0, y2); Blue(); Vertex((j + 1) / 20.0, y1); Vertex(j / 20.0, y1); Vertex(j / 20.0, y1); Vertex((j + 1) / 20.0, y1); Vertex((j + 1) / 20.0, 0.); Vertex(j / 20.0, 0.); } glEnd(); glBegin(GL_TRIANGLES); Blue(); Vertex(0., 1.); Vertex(x1, 1.); Vertex(0., y4); Vertex(0., y1); Vertex(x1, 0.); Vertex(0., 0.); White(); Vertex(x4, 1.); Cyan(); Vertex(x5, 1.); White(); Vertex(x5, y3); Vertex(x5, y2); Cyan(); Vertex(x5, 0.); White(); Vertex(x4, 0.); Vertex(x5, y3); Vertex(x6, .5); Vertex(x5, y2); Cyan(); Vertex(x5, 1.); Blue(); Vertex(x6, 1.); Cyan(); Vertex(x6, y3); Vertex(x6, y2); Blue(); Vertex(x6, 0.); Cyan(); Vertex(x5, 0.); Blue(); Vertex(x6, 1.); Vertex(x7, 1.); Vertex(x7, y4); Vertex(x7, y1); Vertex(x7, 0.); Vertex(x6, 0.); glEnd(); a0 = a1; } glEndList(); } /* CreateRing() */ /************************************************************** DestroyObj */ static void DestroyObj(void) { int i; for(i = 0; i < OBJ_COUNT; glDeleteLists(Obj[i++], 1)); } /* DestroyObj() */ /************************************************************* InitDisplay */ static void InitDisplay(void) { glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT); glutInitWindowPosition(WINDOW_POS_X, WINDOW_POS_Y); glutSetWindow(WindowHandle = glutCreateWindow(WINDOW_TITLE)); glutDisplayFunc(Render); glutKeyboardFunc(Keyboard); glutIdleFunc(Animate); glEnable(GL_BLEND); glEnable(GL_POINT_SMOOTH); glEnable(GL_LINE_SMOOTH); glEnable(GL_POLYGON_SMOOTH); glEnable(GL_NORMALIZE); glDisable(GL_DEPTH_TEST); glDisable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glShadeModel(GL_SMOOTH); State = STATE_OPEN; FrameCount = 0; FrameLimit = INIT_FRAME_LIMIT; Size = Angle = 0; ProjectilePos = -1; CameraSX = CameraSY = CameraTX = CameraTY = CameraTZ = 0; CameraSZ = 200; } /* InitDisplay() */ /**************************************************************** Keyboard */ static void Keyboard(unsigned char c, int u, int v) { glFinish(); DestroyObj(); glutDestroyWindow(WindowHandle); exit(EXIT_SUCCESS); } /* Keyboard() */ /****************************************************************** Render */ static void Render(void) { int width, height; GLfloat dw, dh; glDrawBuffer(GL_BACK); glClear(GL_COLOR_BUFFER_BIT); width = glutGet(GLUT_WINDOW_WIDTH); height = glutGet(GLUT_WINDOW_HEIGHT); if( width > height ) { dw = ((GLfloat)width) / height; dh = 1; } else { dw = 1; dh = ((GLfloat)height) / width; } glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-dw * PERSP_SCALE, dw * PERSP_SCALE, -dh * PERSP_SCALE, dh * 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(); } /* Render() */