终于下完了,回去欣赏下。
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <GL/glut.h> #define WINDOW_WIDTH 600 #define WINDOW_HEIGHT 640 #define WINDOW_X 200 #define WINDOW_Y 200 #define FRAME_PER_SECOND 20 #define KEY_EXIT 27 #define POINT_NUM 200 #define MATRIX_NUM 8 #define bgRand(m) ((float)(rand() % 10000) * m / 10000.0f) typedef struct bgPoint { float x, y; float vx, vy; int r; int g; int b; }BGPoint; typedef BGPoint* Point; typedef struct bgMatrix { BGPoint point[POINT_NUM]; int timer; int targetTime; int pauseTime; }BGMatrix; typedef BGMatrix* Matrix; Matrix* matrix; void handleKeyEvent(unsigned char key, int x, int y); void handleMouseEvent(int button, int state, int x, int y); void handleReshape(int width, int height); void run(int null); void repaint(void); void update(void); void initScene(void); void doScene(void); void drawScene(void); void exitScene(void); void initMatrix(void); void doMatrix(void); void drawMatrix(void); Matrix creatSubMatrix(int subMatrxId); void freeSubMatrix(int subMatrxId); void sleepMilliSeconds(long milliSeconds); int main(int argc, char ** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT); glutInitWindowPosition(WINDOW_X, WINDOW_Y); glutCreateWindow("BestMatrix"); glutKeyboardFunc(handleKeyEvent); glutMouseFunc(handleMouseEvent); glutReshapeFunc(handleReshape); initScene(); glutDisplayFunc(repaint); glutTimerFunc(FRAME_PER_SECOND, run, 0); glutMainLoop(); return 0; } void run(int null) { clock_t startTime, endTime; startTime = clock(); update(); repaint(); endTime = clock(); if (endTime - startTime < FRAME_PER_SECOND) { sleepMilliSeconds(FRAME_PER_SECOND - (endTime - startTime)); } glutPostRedisplay(); glutTimerFunc(FRAME_PER_SECOND, run, 0); } void update(void) { doScene(); } void repaint(void) { glClear(GL_COLOR_BUFFER_BIT); drawScene(); glutSwapBuffers(); } void initScene(void) { srand(time(0)); initMatrix(); glPointSize(3.0); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluOrtho2D(0, (GLdouble)WINDOW_WIDTH, 0, (GLdouble)WINDOW_HEIGHT); glClearColor(0.0, 0.0, 0.0, 0.0); glShadeModel(GL_FLAT); glEnable(GL_COLOR_MATERIAL); } void doScene(void) { doMatrix(); } void drawScene(void) { drawMatrix(); } void exitScene(void) { exit(0); } void initMatrix(void) { int i; matrix = malloc(sizeof(Matrix) * MATRIX_NUM); for (i = 0; i < MATRIX_NUM; i++) { matrix[i] = creatSubMatrix(i); } } void doMatrix() { int i, j; for (i = 0; i < MATRIX_NUM; i++) { if (matrix[i]->timer++ > matrix[i]->targetTime) { for (j = 0; j < POINT_NUM; j++) { matrix[i]->point[j].vy += 0.1f; matrix[i]->point[j].x += matrix[i]->point[j].vx; matrix[i]->point[j].y += matrix[i]->point[j].vy; } } if (matrix[i]->timer > matrix[i]->targetTime + matrix[i]->pauseTime) { freeSubMatrix(i); matrix[i] = creatSubMatrix(i); } } } void drawMatrix(void) { int i, j; unsigned char r, g, b; for (i = 0; i < MATRIX_NUM; i++) { for (j = 0; j < POINT_NUM; j++) { r = matrix[i]->point[j].r; g = matrix[i]->point[j].g; b = matrix[i]->point[j].b; glColor3ub(r, g, b); glBegin(GL_POINTS); glVertex2f(matrix[i]->point[j].x, WINDOW_HEIGHT-matrix[i]->point[j].y); glEnd(); } } } Matrix creatSubMatrix(int subMatrxId) { Matrix matrix; float x, y; int r, g, b; int i; matrix = malloc(sizeof(BGMatrix)); matrix->timer = 0; matrix->targetTime = rand()%50; matrix->pauseTime = 50; x = 20.0f + bgRand(600.0f); y = 100.f + bgRand(100.0f); r = 50 + rand()%(255-50); g = 50 + rand()%(255-50); b = 50 + rand()%(255-50); for (i = 0; i < POINT_NUM; i++) { matrix->point[i].x = x; matrix->point[i].y = y; matrix->point[i].vx = 1.0f - bgRand(2.0f); matrix->point[i].vy = 1.0f - bgRand(2.0f); matrix->point[i].r = r; matrix->point[i].g = g; matrix->point[i].b = b; } return matrix; } void freeSubMatrix(int subMatrxId) { free(matrix[subMatrxId]); } void handleKeyEvent(unsigned char key, int x, int y) { switch (key) { case KEY_EXIT: exitScene(); break; default: break; } } void handleMouseEvent(int button, int state, int x, int y) { switch (button) { case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN) glutIdleFunc(repaint); break; case GLUT_RIGHT_BUTTON: if (state == GLUT_DOWN) glutIdleFunc(NULL); break; default: break; } } void handleReshape(int width, int height) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, (GLdouble)width, 0, (GLdouble)height); } void sleepMilliSeconds(long milliSeconds) { clock_t start, end; start = clock(); end = start + milliSeconds; while (start < end) { start = clock(); } }