//粒子集散开,均匀分布正方形内
#include <GL/glut.h>
#include <stdio.h>
#include <math.h> // 数学函数头文件
#include <olectl.h>
#define RADIUS 4
#define WIDTH_HEIGHT_RATIO 2
#define WINDOW_HEIGHT 500
#define WINDOW_WIDTH WINDOW_HEIGHT * WIDTH_HEIGHT_RATIO
#define MAX_PARTICLES 100 //定义粒子的数目,就目前的程序健壮性,请设为9
int x = RADIUS;
float r1 = 0.0,g1 = 1.0,b1 = 0.0; //正方形颜色的设定,初始化
int flagStop = 0,m = 0;
//////////////////////////////////////////////////////////////////////
typedef struct
{
float r,g,b; // 粒子的颜色
float x,y; // 粒子位置
float xSpeed,ySpeed; // 粒子的速度
float xAddspeed,yAddspeed;
} PARTICLES;
PARTICLES particle[MAX_PARTICLES]; // 粒子系统数组
// 粒子颜色数组
static GLfloat colors[12][3]=
{
{1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 1.0f}, {1.0f, 1.0f, 0.0f},
{1.0f, 0.0f, 1.0f}, {0.0f, 1.0f, 1.0f},{1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 0.0f},{1.0f, 0.0f, 1.0f}, {0.0f, 1.0f, 1.0f}
};
static GLfloat speeds[12][2]= //粒子的速度
{
{12.0f,13.0f}, {3.0f,2.0f}, {7.0f,9.0f}, {8.0f,13.0f},
{14.0f,44.0f}, {39.0f,46.0f}, {33.0f,45.0f}, {32.0f,12.0f},
{22.0f,12.0f}, {9.0f,21.0f}, {21.0f,9.0f}, {8.0f,21.0f}
};
/*
数组实现的
*/
static GLfloat setlocation[][2]= //粒子进入 正方形后的 位置
{
{650.0f,150.0f}, {650.0f,250.0f}, {650.0f,350.0f},
{750.0f,150.0f}, {750.0f,250.0f}, {750.0f,350.0f},
{850.0f,150.0f}, {850.0f,250.0f}, {850.0f,350.0f},
};
void ParticleInit()
{
int loop;
for (loop = 0; loop < MAX_PARTICLES; ++loop)
{
particle[loop].r = colors[rand()%12][0]; // 粒子颜色的红色分量
particle[loop].g = colors[rand()%12][1]; // 粒子颜色的绿色分量
particle[loop].b = colors[rand()%12][2]; // 粒子颜色的蓝色分量
particle[loop].xSpeed = speeds[rand()%12][0]; // 沿x轴的随机速度
particle[loop].ySpeed = speeds[rand()%12][1];; // 沿y轴的随机速度
//particle[loop].zSpeed = (float)(rand()%150); // 沿z轴的随机速度(0,150)
}
}
void Draw(int x ,int y)
{
glPushMatrix(); //保存现在的位置
glTranslatef(x,y,0); //移动
glScalef(RADIUS,RADIUS,0); //放大 倍
glutSolidSphere(1.5f, 10, 10); //渲染一个球
glPopMatrix(); //恢复以前的保存
}
void DrawParticle(void)
{
float x,y,r,g,b;
int loop;
for (loop=0; loop < MAX_PARTICLES; ++loop)
{
x = particle[loop].x; // 定义粒子坐标
y = particle[loop].y;
r = particle[loop].r;
g = particle[loop].g;
b = particle[loop].b;
glColor3f(r,g,b);
Draw(x,y);
}
}
void UpdatePosition()
{
int loop;
for(loop = 0;loop < MAX_PARTICLES;++loop)
{
particle[loop].x += particle[loop].xSpeed;
if(particle[loop].x > 550 & particle[loop].x < 950 & particle[loop].y > 50 & particle[loop].y < 450)
{
m ++;
if(m < 400)
{
particle[loop].x = setlocation[rand()%9][0]; //for寻环实现 闪烁抖动
particle[loop].y = setlocation[rand()%9][1];
}
else
{
for(loop = 0;loop < MAX_PARTICLES;++loop)
{
particle[loop].x = setlocation[loop][0];
particle[loop].y = setlocation[loop][1];
}
}
//正方形的坐标点
}
else
{
//控制 x 坐标
if( particle[loop].x > WINDOW_WIDTH - RADIUS)
{
particle[loop].x = WINDOW_WIDTH - RADIUS;
particle[loop].xSpeed = -particle[loop].xSpeed ;
}
else if(particle[loop].x < RADIUS)
{
x = RADIUS;
particle[loop].xSpeed = -particle[loop].xSpeed ;
}
//控制 y 坐标
particle[loop].y += particle[loop].ySpeed;
if(particle[loop].y > (WINDOW_HEIGHT - RADIUS))
{
particle[loop].y = WINDOW_HEIGHT - RADIUS;
particle[loop].ySpeed = -particle[loop].ySpeed;
}
else if( particle[loop].y < RADIUS)
{
particle[loop].y = RADIUS;
particle[loop].ySpeed = -particle[loop].ySpeed;
}
}
}
}
void myinit()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, WINDOW_WIDTH, 0, WINDOW_HEIGHT);
glMatrixMode(GL_MODELVIEW);
glClearColor (0.0, 0.0, 0.0, 1.0); //背景颜色的设定(1,1,1)白色,(0,0,0)黑色
ParticleInit();
}
//////////////////////////////////////////////////////xin tian
void triangle (GLsizei mode)
{
if(mode == 1)
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);//多边形模式为线框
else
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); //多边形模式为填充多边形
// glBegin(GL_TRIANGLES);//三角形 三个点画一个三角形,剩下的不足三个舍掉
glBegin(GL_POLYGON);//
glColor3f(r1,g1,b1);//设定当前颜色 为绿色
glVertex2f(550.0, 450.0);
glVertex2f(550.0, 50.0);
glVertex2f(950.0, 50.0);
glVertex2f(950.0, 450.0);
glEnd();
}
/*============================================*/
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除场景和深度缓存
DrawParticle();
glViewport(0, 0, 800, 400);//指定从0,0开始(相对于显示窗口的左下角的位置)长宽均为400的
triangle(1);
glutSwapBuffers();// 刷新GL命令队列
}
void TimerFunc(int value)
{
if(0 == flagStop)UpdatePosition();
glutPostRedisplay();
glutTimerFunc(50, TimerFunc, 1);
}
/*============================================*/
void mouse(int btn, int state, int x, int y)
{
if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
flagStop ++;
flagStop = flagStop % 2;
}
glutPostRedisplay();
}
/*============================================*/
void keys1(unsigned char key, int x, int y) //按键控制粒子的速度变化
{
if(key == 'x') // x 加速
{
for(int loop = 0;loop < MAX_PARTICLES;++loop)
{
particle[loop].xSpeed = 1.2 * particle[loop].xSpeed; // 沿x轴的速度
particle[loop].ySpeed = 1.2 * particle[loop].ySpeed; // 沿y轴的速度
}
}
else if(key == 'c') // c 减速
{
for(int loop = 0;loop < MAX_PARTICLES;++loop)
{
particle[loop].xSpeed = 0.8 * particle[loop].xSpeed; // 沿x轴的速度
particle[loop].ySpeed = 0.8 * particle[loop].ySpeed; // 沿y轴的速度
}
}
else if(key == 'z') //z 速度还原
{
for(int loop = 0;loop < MAX_PARTICLES;++loop)
{
particle[loop].xSpeed = speeds[rand()%12][0]; // 沿x轴的随机速度
particle[loop].ySpeed = speeds[rand()%12][1];; // 沿y轴的随机速度
}
}
else if(key == 'v')
{
r1 = colors[rand()%12][0]; // 正方形颜色的红色分量
g1 = colors[rand()%12][1]; // 正方形颜色的绿色分量
b1 = colors[rand()%12][2]; // 正方形颜色的蓝色分量
}
else
{
}
glutPostRedisplay();
}
/*============================================*/
void myReshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, (GLsizei)(w), (GLsizei)(h)); // 重置当前视口大小
}
/*============================================*/
void main(int argc, char **argv)
{
/* Standard GLUT initialization */
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); /* default, not needed */
glutInitWindowSize(800, 800/WIDTH_HEIGHT_RATIO);
glutInitWindowPosition(0,0); /* place window top left on display */
glutCreateWindow("Ball Collision"); /* window title */
/* callback functions */
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutKeyboardFunc(keys1);
glutReshapeFunc (myReshape);
glutTimerFunc(500, TimerFunc, 1); //指定定时器回调函数
myinit(); /* set attributes */
glutMainLoop(); /* enter event loop */
}
本人初学者,欢迎大家共同学习,交流进步。