/* snow1.c - Don Yang (uguu.org) 11/04/01 */ #include #include #include #include #include #include #include #include #define Rand() ((rand() & 4095) / 4095.) typedef struct { double x, y, z, ax, ay, az, sx, sy, sz, ex, ey, ez, rx, ry, rz, st; int obj; } Snowflake; double PI; Snowflake Snow[128]; void RandomPath(double *r, double *a) { int i; r[0] = 8; a[0] = 0; for(i = 1; i < 7; i++) { r[i] = Rand() * 5 + 3; a[i] = Rand() * PI / 6; } r[i] = 3; a[i] = PI / 6; } void CreateSnowflake(Snowflake *f, double ct) { double r[8], a[8]; int i, j; f->x = f->sx = Rand() * 1024 - 512; f->y = f->sy = 256; f->z = f->sz = Rand() * 1024 - 512; f->ex = Rand() * 1024 - 512; f->ey = -256 - Rand() * 1024; f->ez = Rand() * 1024 - 512; f->ax = Rand() * 360; f->rx = Rand() * 10; f->ay = Rand() * 360; f->ry = Rand() * 10; f->az = Rand() * 360; f->rz = Rand() * 10; f->st = ct; RandomPath(r, a); glNewList(f->obj, GL_COMPILE); glBegin(GL_LINE_LOOP); for(i = j = 0; i < 6; i++) { for(; j < 7; j++) glVertex3d(r[j] * cos(i * PI / 3 + a[j]), r[j] * sin(i * PI / 3 + a[j]), 0); for(; j > 0; j--) glVertex3d(r[j] * cos((i + 1) * PI / 3 - a[j]), r[j] * sin((i + 1) * PI / 3 - a[j]), 0); } glEnd(); glEndList(); } void TransformSnowflake(Snowflake *f, double ct) { double t; f->y = f->sy + (f->ey - f->sy) * (t = (ct - f->st) / 16); if( f->y < -256 ) { CreateSnowflake(f, ct); } else { f->x = f->sx + (f->ex - f->sx) * t; f->z = f->sz + (f->ez - f->sz) * t; f->ax += f->rx; f->ay += f->ry; f->az += f->rz; } } void Animate(void) { struct timeb t; double ct; int i; ftime(&t); ct = t.time + t.millitm / 1000.; for(i = 0; i < 128; i++) TransformSnowflake(&Snow[i], ct); glutPostRedisplay(); } void Render(void) { double dw, dh; int w, h, i; glDrawBuffer(GL_BACK); glClear(GL_COLOR_BUFFER_BIT); glViewport(0, 0, w = glutGet(GLUT_WINDOW_WIDTH), h = glutGet(GLUT_WINDOW_HEIGHT)); if( w > h ) { dw = w / (double)h; dh = 1; } else { dw = 1; dh = h / (double)w; } glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-dw, dw, -dh, dh, 10, 2000); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0, 0, -1000, 0, 0, 0, 0, 1, 0); glColor4f(.8, .9, 1, .5); for(i = 0; i < 128; i++) { glPushMatrix(); glTranslated(Snow[i].x, Snow[i].y, Snow[i].z); glRotated(Snow[i].ax, 1, 0, 0); glRotated(Snow[i].ay, 0, 1, 0); glRotated(Snow[i].az, 0, 0, 1); glCallList(Snow[i].obj); glPopMatrix(); } glutSwapBuffers(); glFlush(); } void Reshape(int w, int h) { glutPostRedisplay(); } void Quit(unsigned char c, int u, int v) { int i; glFlush(); for(i = 0; i < 128; i++) glDeleteLists(Snow[i].obj, 1); exit(0); } void Initialize(void) { struct timeb t; double ct; int i; glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutInitWindowSize(640, 480); glutCreateWindow("winter wish"); glutDisplayFunc(Render); glutIdleFunc(Animate); glutReshapeFunc(Reshape); glutKeyboardFunc(Quit); ftime(&t); ct = t.time + t.millitm / 1000.; for(i = 0; i < 128; i++) { Snow[i].obj = glGenLists(1); CreateSnowflake(&Snow[i], ct); Snow[i].ey -= 512; } glEnable(GL_BLEND); glClearColor(0, 0, 0, 0); glBlendFunc(GL_SRC_ALPHA, GL_ONE); } int main(int argc, char **argv) { srand(time(0)); PI = atan2(0, -1); glutInit(&argc, argv); Initialize(); glutMainLoop(); return 0; }