openGL粒子效果讲解
Explanation of openGL particle effect
所以我有这段代码可以使用看起来像是粒子效果的东西来产生烟花,但我不明白代码中发生了什么。谁能给我解释一下,尤其是初始化函数和绘制爆炸函数。如果你能用笔记来注释它那就太棒了。
/* fireworks.c - simulate fireworks with particle systems */
#include <GL/glut.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#ifdef WIN32
//to correct ASCI deviations in Microsoft VC++ 6.0
#define M_PI (3.1415926535897932384626433832795)
double drand48()
{ return (rand()%10000)/10000.0; }
//end of corrections
#endif
#define MAX_POINTS 5000
int numPoints;
GLfloat curx, cury;
GLfloat x[MAX_POINTS], y[MAX_POINTS];
GLfloat xacc[MAX_POINTS], yacc[MAX_POINTS];
GLfloat red, green, blue;
int step; int length;
void initialize()
{ int j; double temp, temp2;
numPoints = drand48()*(MAX_POINTS-1);
curx = -0.5 + drand48();
cury = 0.0 + drand48();
red = 0.5 + 0.5*drand48();
green = 0.5 + 0.5*drand48();
blue = 0.5 + 0.5*drand48();
glPointSize(1.5);
step = 0;
length = 700 + 300*drand48();
/* initialize the blast */
for (j=0 ; j<numPoints ; j++ ) {
x[j] = curx;
y[j] = cury;
temp = drand48();
temp2 = drand48()*2.0*M_PI;
xacc[j] = (cos(temp2) * temp)/length;
yacc[j] = (sin(temp2) * temp)/length;
}
}
void draw_blast(void)
{ int i;
double glow = (length - step) / (double)length;
glColor3f(red*glow, green*glow, blue*glow);
glBegin(GL_POINTS);
for (i=0;i<numPoints;i++) {
x[i] += xacc[i];
y[i] += yacc[i];
glVertex2f(x[i], y[i]);
}
glEnd();
glFlush();
glutSwapBuffers();
}
void display(void)
{ int i;
glClear(GL_COLOR_BUFFER_BIT);
if (step < 0.9*length) {
for (i=0; i<numPoints; i++)
yacc[i] -= 0.02 / length; // gravity
draw_blast();
}
step ++;
if (step > length) initialize();
}
void idle(void)
{
glutPostRedisplay();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27: exit(0); break;
}
}
void reshape (int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-1.0, 1.0,
-1.0*(GLfloat)h/(GLfloat)w, 1.0*(GLfloat)h/(GLfloat)w,
-1.0, 1.0);
else
glOrtho(-1.0*(GLfloat)w/(GLfloat)h, 1.0*(GLfloat)w/(GLfloat)h,
-1.0, 1.0,
-1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (800, 800);
glutInitWindowPosition(0, 0);
glutCreateWindow ("Fireworks");
glClearColor (0.0, 0.0, 0.0, 0.0);
initialize();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
是的,它是一个粒子系统。但是-不是特别有效。
让我们一步一步来:
GLfloat x[MAX_POINTS], y[MAX_POINTS];
GLfloat xacc[MAX_POINTS], yacc[MAX_POINTS];
x
和 y
保持粒子的位置。 xacc
和 yacc
保持速度。
在initialize
中:
numPoints = drand48()*(MAX_POINTS-1);
这会设置随机数量的粒子...
curx = -0.5 + drand48();
cury = 0.0 + drand48();
red = 0.5 + 0.5*drand48();
green = 0.5 + 0.5*drand48();
blue = 0.5 + 0.5*drand48();
glPointSize(1.5);
step = 0;
length = 700 + 300*drand48();
...具有随机的中心位置、颜色和半径 (length
)。
for (j=0 ; j<numPoints ; j++ ) {
这将开始对每个粒子进行初始化。
x[j] = curx;
y[j] = cury;
将粒子的位置设置为中心位置。
temp = drand48();
temp2 = drand48()*2.0*M_PI;
xacc[j] = (cos(temp2) * temp)/length;
yacc[j] = (sin(temp2) * temp)/length;
设置粒子的随机方向 (temp2
) 和基于系统半径的随机速度 (temp / length
)。
在drawBlast()
中:
double glow = (length - step) / (double)length;
glColor3f(red*glow, green*glow, blue*glow);
慢慢将粒子的颜色淡化为黑色。
x[i] += xacc[i];
y[i] += yacc[i];
按粒子的速度推进粒子。这假设帧速率恒定。
glVertex2f(x[i], y[i]);
将粒子画成一个点。
在display()
中:
yacc[i] -= 0.02 / length; // gravity
向下加速每个粒子。 IE。模拟粒子下落。
所以我有这段代码可以使用看起来像是粒子效果的东西来产生烟花,但我不明白代码中发生了什么。谁能给我解释一下,尤其是初始化函数和绘制爆炸函数。如果你能用笔记来注释它那就太棒了。
/* fireworks.c - simulate fireworks with particle systems */
#include <GL/glut.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#ifdef WIN32
//to correct ASCI deviations in Microsoft VC++ 6.0
#define M_PI (3.1415926535897932384626433832795)
double drand48()
{ return (rand()%10000)/10000.0; }
//end of corrections
#endif
#define MAX_POINTS 5000
int numPoints;
GLfloat curx, cury;
GLfloat x[MAX_POINTS], y[MAX_POINTS];
GLfloat xacc[MAX_POINTS], yacc[MAX_POINTS];
GLfloat red, green, blue;
int step; int length;
void initialize()
{ int j; double temp, temp2;
numPoints = drand48()*(MAX_POINTS-1);
curx = -0.5 + drand48();
cury = 0.0 + drand48();
red = 0.5 + 0.5*drand48();
green = 0.5 + 0.5*drand48();
blue = 0.5 + 0.5*drand48();
glPointSize(1.5);
step = 0;
length = 700 + 300*drand48();
/* initialize the blast */
for (j=0 ; j<numPoints ; j++ ) {
x[j] = curx;
y[j] = cury;
temp = drand48();
temp2 = drand48()*2.0*M_PI;
xacc[j] = (cos(temp2) * temp)/length;
yacc[j] = (sin(temp2) * temp)/length;
}
}
void draw_blast(void)
{ int i;
double glow = (length - step) / (double)length;
glColor3f(red*glow, green*glow, blue*glow);
glBegin(GL_POINTS);
for (i=0;i<numPoints;i++) {
x[i] += xacc[i];
y[i] += yacc[i];
glVertex2f(x[i], y[i]);
}
glEnd();
glFlush();
glutSwapBuffers();
}
void display(void)
{ int i;
glClear(GL_COLOR_BUFFER_BIT);
if (step < 0.9*length) {
for (i=0; i<numPoints; i++)
yacc[i] -= 0.02 / length; // gravity
draw_blast();
}
step ++;
if (step > length) initialize();
}
void idle(void)
{
glutPostRedisplay();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27: exit(0); break;
}
}
void reshape (int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-1.0, 1.0,
-1.0*(GLfloat)h/(GLfloat)w, 1.0*(GLfloat)h/(GLfloat)w,
-1.0, 1.0);
else
glOrtho(-1.0*(GLfloat)w/(GLfloat)h, 1.0*(GLfloat)w/(GLfloat)h,
-1.0, 1.0,
-1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (800, 800);
glutInitWindowPosition(0, 0);
glutCreateWindow ("Fireworks");
glClearColor (0.0, 0.0, 0.0, 0.0);
initialize();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(idle);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
是的,它是一个粒子系统。但是-不是特别有效。
让我们一步一步来:
GLfloat x[MAX_POINTS], y[MAX_POINTS];
GLfloat xacc[MAX_POINTS], yacc[MAX_POINTS];
x
和 y
保持粒子的位置。 xacc
和 yacc
保持速度。
在initialize
中:
numPoints = drand48()*(MAX_POINTS-1);
这会设置随机数量的粒子...
curx = -0.5 + drand48();
cury = 0.0 + drand48();
red = 0.5 + 0.5*drand48();
green = 0.5 + 0.5*drand48();
blue = 0.5 + 0.5*drand48();
glPointSize(1.5);
step = 0;
length = 700 + 300*drand48();
...具有随机的中心位置、颜色和半径 (length
)。
for (j=0 ; j<numPoints ; j++ ) {
这将开始对每个粒子进行初始化。
x[j] = curx;
y[j] = cury;
将粒子的位置设置为中心位置。
temp = drand48();
temp2 = drand48()*2.0*M_PI;
xacc[j] = (cos(temp2) * temp)/length;
yacc[j] = (sin(temp2) * temp)/length;
设置粒子的随机方向 (temp2
) 和基于系统半径的随机速度 (temp / length
)。
在drawBlast()
中:
double glow = (length - step) / (double)length;
glColor3f(red*glow, green*glow, blue*glow);
慢慢将粒子的颜色淡化为黑色。
x[i] += xacc[i];
y[i] += yacc[i];
按粒子的速度推进粒子。这假设帧速率恒定。
glVertex2f(x[i], y[i]);
将粒子画成一个点。
在display()
中:
yacc[i] -= 0.02 / length; // gravity
向下加速每个粒子。 IE。模拟粒子下落。