#include "stdafx.h"
#include <stdlib.h>
#include <GL\glut.h>
#include <gl\glaux.h>
#define PARTICLES_NUMBER 1000 // 粒子数量
float slowdown=2.0f; // 用来减小例子速度
float zoom=-40.0f;
GLuint loop; // 用来遍历所有粒子
GLuint col; // 颜色索引
GLuint texture[1]; // 存储粒子的Texture
typedef struct // 粒子结构
{
bool active; // 是否活动
float life; // 生存时间
float fade; // 生命减少速率
float r; // 颜色值Red分量
float g; // Green
float b; // Blue
float x; // 粒子X坐标值
float y; // Y
float z; // Z
float xi; // X方向速度
float yi; // Y
float zi; // Z
float xg; // X加速度
float yg; // Y
float zg; // Z
}
particles; // Particles Structure
particles particle[PARTICLES_NUMBER]; // Particle Array (Room For Particle Info)
static GLfloat colors[12][3]= // Rainbow Of Colors
{
{1.0f,0.5f,0.5f},{1.0f,0.75f,0.5f},{1.0f,1.0f,0.5f},{0.75f,1.0f,0.5f},
{0.5f,1.0f,0.5f},{0.5f,1.0f,0.75f},{0.5f,1.0f,1.0f},{0.5f,0.75f,1.0f},
{0.5f,0.5f,1.0f},{0.75f,0.5f,1.0f},{1.0f,0.5f,1.0f},{1.0f,0.5f,0.75f}
};
AUX_RGBImageRec *LoadBMP(char *Filename) // 载入图片
{
FILE *File=NULL;
if (!Filename)
{
return NULL;
}
File=fopen(Filename,"r");
if (File)
{
fclose(File);
return auxDIBImageLoad(Filename);
}
return NULL;
}
void LoadGLTextures(void) // 载入Texture
{
AUX_RGBImageRec *TextureImage[1];
memset(TextureImage,0,sizeof(void *)*1);
if (TextureImage[0]=LoadBMP("Data/Star.bmp"))
{
glGenTextures(1, texture); // Create One Texture
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
}
}
void ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window
{
if (height==0) // Prevent A Divide By Zero By
{
height=1; // Making Height Equal One
}
glViewport(0,0,width,height); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,200.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
}
void InitGL(void)
{
LoadGLTextures();
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f,0.0f,0.0f,0.0f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glDisable(GL_DEPTH_TEST); // Disable Depth Testing
glEnable(GL_BLEND); // Enable Blending
glBlendFunc(GL_SRC_ALPHA,GL_ONE); // Type Of Blending To Perform
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); // Really Nice Perspective Calculations
glHint(GL_POINT_SMOOTH_HINT,GL_NICEST); // Really Nice Point Smoothing
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glBindTexture(GL_TEXTURE_2D,texture[0]); // Select Our Texture
for (loop=0;loop<PARTICLES_NUMBER;loop++) // 初始化粒子
{
particle[loop].active=true;
particle[loop].life=1.0f; // 生存周期
particle[loop].fade=float(rand()%100)/1000.0f+0.003f;
particle[loop].r=colors[loop*(12/PARTICLES_NUMBER)][0];
particle[loop].g=colors[loop*(12/PARTICLES_NUMBER)][1];
particle[loop].b=colors[loop*(12/PARTICLES_NUMBER)][2];
particle[loop].xi=float((rand()%50)-25.0f)*10.0f;
particle[loop].yi=float((rand()%50)-25.0f)*10.0f;
particle[loop].zi=float((rand()%50)-25.0f)*10.0f;
particle[loop].xg=0.0f;
particle[loop].yg=-0.7f; //y方向的加速度(重力模型)
particle[loop].zg=0.0f;
}
}
void DrawGLScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
for (loop=0;loop<PARTICLES_NUMBER;loop++) //遍历每一个粒子
{
if (particle[loop].active)
{
float x=particle[loop].x;
float y=particle[loop].y;
float z=particle[loop].z+zoom;
col++; //为每一个粒子赋不同的颜色值
if(col>11) col=0;
glColor4f(particle[loop].r,particle[loop].g,particle[loop].b,particle[loop].life);
glBegin(GL_TRIANGLE_STRIP); // Build Quad From A Triangle Strip
glTexCoord2d(1,1); glVertex3f(x+0.5f,y+0.5f,z); // Top Right
glTexCoord2d(0,1); glVertex3f(x-0.5f,y+0.5f,z); // Top Left
glTexCoord2d(1,0); glVertex3f(x+0.5f,y-0.5f,z); // Bottom Right
glTexCoord2d(0,0); glVertex3f(x-0.5f,y-0.5f,z); // Bottom Left
glEnd();
particle[loop].x+=particle[loop].xi/(slowdown*500);//改变粒子在x轴上的位置
particle[loop].y+=particle[loop].yi/(slowdown*100);//Y
particle[loop].z+=particle[loop].zi/(slowdown*500);//Z
//particle[loop].xi+=particle[loop].xg; //X方向速度值
particle[loop].yi+=particle[loop].yg*(1.0f-particle[loop].life); //Y方向的速度值
//particle[loop].zi+=particle[loop].zg; // Z方向的速度值
particle[loop].life-=particle[loop].fade; // 粒子的生存的剩余时间
if (particle[loop].life<0.0f) // 如果粒子的生命结束,则对其重新赋予新的生命
{
particle[loop].life=1.0f;
particle[loop].fade=float(rand()%100)/1000.0f+0.003f;
particle[loop].x=0.0f;
particle[loop].y=0.0f;
particle[loop].z=0.0f;
particle[loop].xi=float((rand()%50)-25.0f);
particle[loop].yi=float((rand()%50)-25.0f);
particle[loop].zi=float((rand()%50)-25.0f);
particle[loop].yg=-0.7f; // Y方向上的加速度值(重力模型)
if(particle[loop].yi<10) particle[loop].yi=20;//-particle[loop].yi;//保证粒子的初始方向向上
particle[loop].r=colors[col][0];//颜色值
particle[loop].g=colors[col][1];
particle[loop].b=colors[col][2];
}
}
}
glutSwapBuffers();
}
void TimerFunction(int value)
{
glutPostRedisplay();
glutTimerFunc(10,TimerFunction,1);
}
int main(int argc, _TCHAR* argv[])
{
glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH|GLUT_RGB);
glutInitWindowSize(800,800);
glutInitWindowPosition(100,100);
glutCreateWindow("Zhuang Xiaolong's Particles");
InitGL();
glutDisplayFunc(DrawGLScene);
glutReshapeFunc(ReSizeGLScene);
glutTimerFunc(10,TimerFunction,1);
glutMainLoop();
return 0;
}