/* aya7.c - Don Yang (uguu.org) 10/07/06 */ #include #include #include #include #include double PI, ColorCurveR[] = { .9, .98, 1, 0, -1 }, ColorCurveGB[] = { .32, .98, .36, .12, .54, .12, .58, .98, .9, .98, 1, 0, -1 }, ColorCurveA[] = { .56, .99, .58, .7, .9, 0, -1 }, CurrentTime, x, r, ix0, iy0, ix1, iy1; struct { double t0, x, y, r0, r1; } GlobalEmitter; int i, j, k, TextureHandle, SpriteHandle; unsigned char TextureImage[16384], *p; double RandomRange(double u) { return u * (rand() & 0x3fff) / 8191. - u; } UpdateClock() { struct timeval t; gettimeofday(&t, NULL); CurrentTime = t.tv_sec + t.tv_usec / 1e6; } Render() { UpdateClock(); srand(CurrentTime); glDrawBuffer(GL_BACK); glClear(GL_COLOR_BUFFER_BIT); glViewport(0, 0, i = glutGet(GLUT_WINDOW_WIDTH), j = glutGet(GLUT_WINDOW_HEIGHT)); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if( i > j ) gluOrtho2D(-i / (double)j, i / (double)j, -1, 1); else gluOrtho2D(-1, 1, -j / (double)i, j / (double)i); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); ix0 = (CurrentTime - GlobalEmitter.t0) / 1.5; for(i = 0; i < 23; i++) { if( (ix1 = ix0 - i / 23.) >= 0 ) { r = ix1 * 2.1; for(j = 0; j < 32; j++) { x = GlobalEmitter.r0 + j * PI / 16.; iy1 = ix1 * ((GlobalEmitter.r1 + j * PI / 16.) - x) + x; if( i & 1 ) iy1 += PI / 32; glPushMatrix(); glTranslated(r * cos(iy1) + GlobalEmitter.x, r * sin(iy1) + GlobalEmitter.y, 0); glCallList(SpriteHandle); glPopMatrix(); } } } if( ix0 > 2.2 ) { GlobalEmitter.t0 = CurrentTime; GlobalEmitter.r0 = GlobalEmitter.r1 = RandomRange(PI); if( !(rand() & 3) ) GlobalEmitter.r1 += RandomRange(PI / 3); GlobalEmitter.x = RandomRange(.5); GlobalEmitter.y = RandomRange(.5); } glutSwapBuffers(); glFlush(); } RenderFirstFrame() { UpdateClock(); glGenTextures(1, &TextureHandle); glBindTexture(GL_TEXTURE_2D, TextureHandle); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, TextureImage); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glEnable(GL_BLEND); glEnable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glNewList(SpriteHandle = glGenLists(1), GL_COMPILE); glBegin(GL_TRIANGLE_FAN); glTexCoord2d(0, 0); glVertex2d(-.07, -.07); glTexCoord2d(1, 0); glVertex2d( .07, -.07); glTexCoord2d(1, 1); glVertex2d( .07, .07); glTexCoord2d(0, 1); glVertex2d(-.07, .07); glEnd(); glEndList(); GlobalEmitter.t0 = CurrentTime; GlobalEmitter.x = GlobalEmitter.y = GlobalEmitter.r0 = GlobalEmitter.r1 = 0; glutDisplayFunc(Render); Render(); } Animate() { glutPostRedisplay(); } Reshape(int w, int h) { Animate(); } Quit(unsigned char c, int u, int v) { glFlush(); glDeleteLists(SpriteHandle, 1); glDeleteTextures(1, &TextureHandle); exit(0); } double StepFunc(double *curve) { ix0 = *curve++; iy0 = *curve++; if( r > ix0 ) { for(; (ix1 = *curve++) > ix0;) { iy1 = *curve++; if( r < ix1 ) { iy0 = (iy1 - iy0) * (r - ix0) / (ix1 - ix0) + iy0; break; } ix0 = ix1; iy0 = iy1; } } return 255 * iy0; } main(int argc, char **argv) { glutInit(&argc, argv); PI = atan2(0, -1); for(i = 0; i < 16384; TextureImage[i++] = 0); p = TextureImage; for(i = 0; i < 64; i++) { x = i / 32. - 1; for(j = 0; j < 64; j++) { r = j / 32. - 1; r = sqrt(x * x + r * r); if( (k = StepFunc(ColorCurveR)) > 255 ) k = 255; *p++ = k; if( (k = StepFunc(ColorCurveGB)) > 255 ) k = 255; *p++ = k; *p++ = k; if( (k = StepFunc(ColorCurveA)) > 255 ) k = 255; *p++ = k; } } glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutSetWindow(glutCreateWindow("Aya")); glutDisplayFunc(RenderFirstFrame); glutIdleFunc(Animate); glutReshapeFunc(Reshape); glutKeyboardFunc(Quit); glutMainLoop(); }