终于下完了,回去欣赏下。


程序代码:#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();
}
}
