opengl粒子系统实现.doc_第1页
opengl粒子系统实现.doc_第2页
opengl粒子系统实现.doc_第3页
opengl粒子系统实现.doc_第4页
opengl粒子系统实现.doc_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

OpenGL进阶(六)-粒子系统/qp120291570/article/details/8373896一、提要 有一款例子特效软件叫做particle illution,在影视后期和游戏制作领域都可以用到,相信很多人都接触过,今天我们用SDL+OpenGL来实现例子效果。确保你搞定了物理模拟的代码! 代码下载二、原理简介 所谓的例子系统,就是同时控制一大堆类似的对象,这些对象可能是形体,可能是图片,有着不同的特征(寿命,速度,位置)。有了之前的基础,我们可以很轻易地搞定今天的东西。三、代码清单首先是粒子的头文件,我直接写成结构体了,里面有一些基本的属性。cppview plaincopy1. /*2. Copyright:2012,ustcAllrightsreserved.3. contact:4. Filename:particle.h5. Description:Particalinopengl.6. Author:SilangQuan7. Version:1.08. Date:2012.12.209. */10. #ifndefPARTICLE_H11. #definePARTICLE_H12. #includevector3d.h13. typedefstruct14. 15. floatr;16. floatg;17. floatb;18. floatalpha;19. Color;20. 21. typedefstruct22. 23. Vector3Dposition;24. Vector3Dvelocity;25. Vector3Dacceleration;26. Colorcolor;27. floatage;28. floatlife;29. floatsize;30. Particle;31. 32. #endif/PARTICLE_Hcppview plaincopy1. /*2. Copyright:2012,ustcAllrightsreserved.3. contact:4. Filename:particle.h5. Description:Particalinopengl.6. Author:SilangQuan7. Version:1.08. Date:2012.12.209. */10. #ifndefPARTICLE_H11. #definePARTICLE_H12. #includevector3d.h13. typedefstruct14. 15. floatr;16. floatg;17. floatb;18. floatalpha;19. Color;20. 21. typedefstruct22. 23. Vector3Dposition;24. Vector3Dvelocity;25. Vector3Dacceleration;26. Colorcolor;27. floatage;28. floatlife;29. floatsize;30. Particle;31. 32. #endif/PARTICLE_H我们用球体来模拟例子,所以size表示的就是球体的半径。接下来是粒子系统类(类名拼写错了*-*)cppview plaincopy1. /*2. Copyright:2012,ustcAllrightsreserved.3. contact:4. Filename:particalsystem.h5. Description:Particalinopengl.6. Author:SilangQuan7. Version:1.08. Date:2012.12.209. */10. 11. #ifndefPARTICALSYSTEM_H12. #definePARTICALSYSTEM_H13. #include14. #include15. #include16. #include17. #include18. #include19. #include20. #includeparticle.h21. #definePI3.141592622. usingnamespacestd;23. classParticalSystem24. 25. public:26. ParticalSystem();27. ParticalSystem(int_count,float_gravity)ptlCount=_count;gravity=_gravity;28. voidinit();29. voidsimulate(floatdt);30. voidaging(floatdt);31. voidapplyGravity();32. voidkinematics(floatdt);33. voidrender();34. virtualParticalSystem();35. protected:36. private:37. intptlCount;38. floatgravity;39. GLUquadricObj*mySphere;40. vectorparticles;41. ;42. 43. #endif/PARTICALSYSTEM_Hcppview plaincopy1. /*2. Copyright:2012,ustcAllrightsreserved.3. contact:4. Filename:particalsystem.h5. Description:Particalinopengl.6. Author:SilangQuan7. Version:1.08. Date:2012.12.209. */10. 11. #ifndefPARTICALSYSTEM_H12. #definePARTICALSYSTEM_H13. #include14. #include15. #include16. #include17. #include18. #include19. #include20. #includeparticle.h21. #definePI3.141592622. usingnamespacestd;23. classParticalSystem24. 25. public:26. ParticalSystem();27. ParticalSystem(int_count,float_gravity)ptlCount=_count;gravity=_gravity;28. voidinit();29. voidsimulate(floatdt);30. voidaging(floatdt);31. voidapplyGravity();32. voidkinematics(floatdt);33. voidrender();34. virtualParticalSystem();35. protected:36. private:37. intptlCount;38. floatgravity;39. GLUquadricObj*mySphere;40. vectorparticles;41. ;42. 43. #endif/PARTICALSYSTEM_H解释一下几个重要函数:init:做一些例子系统的初始化工作;aging:计算粒子的年龄;applyGravity:向粒子施加重力;kinematics:这个单词的意思是运动学,所以就是负责管理粒子的加速,位移;simulate:例子模拟的总负责函数;render:渲染粒子;然后来看函数是怎么实现的:cppview plaincopy1. /*2. Copyright:2012,ustcAllrightsreserved.3. contact:4. Filename:particalsystem.Cpp5. Description:Particalinopengl.6. Author:SilangQuan7. Version:1.08. Date:2012.12.229. */10. 11. #includeparticalsystem.h12. 13. ParticalSystem:ParticalSystem()14. 15. /ctor16. 17. 18. ParticalSystem:ParticalSystem()19. 20. /dtor21. 22. 23. voidParticalSystem:init()24. 25. inti;26. srand(unsigned(time(0);27. Colorcolors3=0,0,1,1,1,0,1,1;28. for(i=0;iptlCount;i+)29. 30. /theta=(rand()%361)/360.0*2*PI;31. Particletmp=Vector3D(0,0,0),Vector3D(rand()%50)-26.0f),(rand()%50)-26.0f),(rand()%50)-26.0f),Vector3D(0,0,0),colorsrand()%2,0.0f,0.5+0.05*(rand()%10),0.3f;32. particles.push_back(tmp);33. 34. mySphere=gluNewQuadric();35. 36. voidParticalSystem:simulate(floatdt)37. 38. aging(dt);39. applyGravity();40. kinematics(dt);41. 42. voidParticalSystem:aging(floatdt)43. 44. for(vector:iteratoriter=particles.begin();iter!=particles.end();iter+)45. 46. iter-age+=dt;47. if(iter-ageiter-life)48. 49. iter-position=Vector3D(0,0,0);50. iter-age=0.0;51. iter-velocity=Vector3D(rand()%30)-15.0f),(rand()%30)-11.0f),(rand()%30)-15.0f);52. 53. 54. 55. voidParticalSystem:applyGravity()56. 57. for(vector:iteratoriter=particles.begin();iter!=particles.end();iter+)58. iter-acceleration=Vector3D(0,gravity,0);59. 60. 61. voidParticalSystem:kinematics(floatdt)62. 63. for(vector:iteratoriter=particles.begin();iter!=particles.end();iter+)64. 65. iter-position=iter-position+iter-velocity*dt;66. iter-velocity=iter-velocity+iter-acceleration*dt;67. 68. 69. voidParticalSystem:render()70. 71. 72. for(vector:iteratoriter=particles.begin();iter!=particles.end();iter+)73. 74. floatalpha=1-iter-age/iter-life;/calculatethealphavalueaccordingtotheageofparticle.75. Vector3Dtmp=iter-position;76. glColor4f(iter-color.r,iter-color.g,iter-color.b,alpha);77. glPushMatrix();78. glTranslatef(tmp.x,tmp.y,tmp.z);79. gluSphere(mySphere,iter-size,32,16);80. glPopMatrix();81. 82. 83. cppview plaincopy1. /*2. Copyright:2012,ustcAllrightsreserved.3. contact:4. Filename:particalsystem.Cpp5. Description:Particalinopengl.6. Author:SilangQuan7. Version:1.08. Date:2012.12.229. */10. 11. #includeparticalsystem.h12. 13. ParticalSystem:ParticalSystem()14. 15. /ctor16. 17. 18. ParticalSystem:ParticalSystem()19. 20. /dtor21. 22. 23. voidParticalSystem:init()24. 25. inti;26. srand(unsigned(time(0);27. Colorcolors3=0,0,1,1,1,0,1,1;28. for(i=0;iptlCount;i+)29. 30. /theta=(rand()%361)/360.0*2*PI;31. Particletmp=Vector3D(0,0,0),Vector3D(rand()%50)-26.0f),(rand()%50)-26.0f),(rand()%50)-26.0f),Vector3D(0,0,0),colorsrand()%2,0.0f,0.5+0.05*(rand()%10),0.3f;32. particles.push_back(tmp);33. 34. mySphere=gluNewQuadric();35. 36. voidParticalSystem:simulate(floatdt)37. 38. aging(dt);39. applyGravity();40. kinematics(dt);41. 42. voidParticalSystem:aging(floatdt)43. 44. for(vector:iteratoriter=particles.begin();iter!=particles.end();iter+)45. 46. iter-age+=dt;47. if(iter-ageiter-life)48. 49. iter-position=Vector3D(0,0,0);50. iter-age=0.0;51. iter-velocity=Vector3D(rand()%30)-15.0f),(rand()%30)-11.0f),(rand()%30)-15.0f);52. 53. 54. 55. voidParticalSystem:applyGravity()56. 57. for(vector:iteratoriter=particles.begin();iter!=particles.end();iter+)58. iter-acceleration=Vector3D(0,gravity,0);59. 60. 61. voidParticalSystem:kinematics(floatdt)62. 63. for(vector:iteratoriter=particles.begin();iter!=particles.end();iter+)64. 65. iter-position=iter-position+iter-velocity*dt;66. iter-velocity=iter-velocity+iter-acceleration*dt;67. 68. 69. voidParticalSystem:render()70. 71. 72. for(vector:iteratoriter=particles.begin();iter!=particles.end();iter+)73. 74. floatalpha=1-iter-age/iter-life;/calculatethealphavalueaccordingtotheageofparticle.75. Vector3Dtmp=iter-position;76. glColor4f(iter-color.r,iter-color.g,iter-color.b,alpha);77. glPushMatrix();78. glTranslatef(tmp.x,tmp.y,tmp.z);79. gluSphere(mySphere,iter-size,32,16);80. glPopMatrix();81. 82. 83. 实现还是比较简单的,下面渲染看一下.首先要在initGL函数中添加两句话:cppview plaincopy1. glEnable(GL_BLEND);2. glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);cppview plaincopy1. glEnable(GL_BLEND);2. glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);这样透明度才会有效。接着初始化一个例子系统,并对例子进行初始化:cppview plaincopy1. ParticalSystemps;cppview plaincopy1. ParticalSystemps;plainview plaincopy1. intmain(intargc,char*argv)2. 3. /Colordepthinbitsofourwindow.4. intflags=SDL_OPENGL|SDL_RESIZABLE;5. /SettheSDL6. initSDL(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,flags);7. /SettheOpenGL8. initGL(SCREEN_WIDTH,SCREEN_HEIGHT);9. ps=ParticalSystem(100,-15.0);10. ps.init();11. /mainloop12. while(true)13. 14. /*Processincomingevents.*/15. handleEvents();16. ps.simulate(0.01);17. /*Drawthescreen.*/18. renderGL();19. 20. return0;21. plainview plaincopy1. intmain(intargc,char*argv)2. 3. /Colordepthinbitsofourwindow.4. intflags=SDL_OPENGL|SDL_RESIZABLE;5. /SettheSDL6. initSDL(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,flags);7. /SettheOpenGL8. initGL(SCREEN_WIDTH,SCREEN_HEIGHT);9. ps=ParticalSystem(100,-15.0);10. ps.init();11. /mainloop12. while(true)13. 14. /*Processincomingevents.*/15. handleEvents();16. ps.simulate(0.01);17. /*Drawthescreen.*/18. renderGL();19. 20. return0;21. 然后是渲染函数:cppview plaincopy1. voidrenderGL()2. 3. /Clearthecoloranddepthbuffers.4. glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);5. /Wedontwanttomodifytheprojectionmatrix.*/6. glMatrixMode(GL_MODELVIEW);7. glLoadIdentity();8. /Movedownthez-axis.9. glTranslatef(0.0f,0.0f,-35.0f);10. ps.render();11. SDL_GL_SwapBuffers();12. cppview plaincopy1. voidrenderGL()2. 3. /Clearthecoloranddepthbuffers.4. glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);5. /Wedontwanttomodifytheprojectionmatrix.*/6. glMatrixMode(GL_MODELVIEW);7. glLoadIdentity();8. /Movedownthez-axis.9. glTranslatef(0.0f,0.0f,-35.0f);10. ps.render();11. SDL_GL_SwapBuffers();12. 跑一下:效果还是不错的下面我们来实现一些更棒的效果!四、动态模糊和碰撞检测动态模糊的实现比较简单,主循环不再每次把整个画面清空,而是每帧画一个半透明的黑色长方形,就可以模拟动态模糊(motion blur)的效果。将之前的cppview plaincopy1. /Clearthecoloranddepthbuffers.2. glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);cppview plaincopy1. /Clearthecoloranddepthbuffers.2. glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);改成cppview plaincopy1. /Clearthedepthbuffers.2. glClear(GL_DEPTH_BUFFER_BIT);cppview plaincopy1. /Clearthedepthbuffers.2. glClear(GL_DEPTH_BUFFER_BIT);然后在例子系统的render函数中添加画矩形的代码:cppview plaincopy1. voidParticalSystem:render()2. 3. 4. for(vector:iteratoriter=particles.begin();iter!=particles.end();iter+)5. 6. floatalpha=1-iter-age/iter-life;7. Vector3Dtmp=iter-position;8. glColor4f(iter-color.r,iter-color.g,iter-color.b,alpha);9. /glColor4f(1.0f,1.0f,1.0f,0.1);10. glPushMatrix();11. glTranslatef(tmp.x,tmp.y,tmp.z);12. gluSphere(mySphere,iter-size,32,16);13. glPopMatrix();14. 15. 16. /Motionblue17. glColor4f(0.0f,0.0f,0.0f,0.1);18. glBegin(GL_QUADS);19. glVertex3f(-20.0f,-20.0f,20.0f);20. glVertex3f(20.0f,-20.0f,20.0f);21. glVertex3f(20.0f,20.0f,20.0f);22. glVertex3f(-20.0f,20.0f,20.0f);23. glEnd();24. 25. cppview plaincopy1. voidParticalSystem:render()2. 3. 4. for(vector:iteratoriter=particles.begin();iter!=particles.end();iter+)5. 6. floatalpha=1-iter-age/iter-life;7. Vector3Dtmp=iter-position;8. glColor4f(iter-color.r,iter-color.g,iter-color.b,alpha);9. /glColor4f(1.0f,1.0f,1.0f,0.1);10. glPushMatrix();11. glTranslatef(tmp.x,tmp.y,tmp.z);12. gluSphere(mySphere,iter-size,32,16);13. glPopMatrix();14. 15. 16. /Motionblue17. glColor4f(0.0f,0.0f,0.0f,0.1);18. glBegin(GL_QUADS);19. glVertex3f(-20.0f,-20.0f,20.0f);20. glVertex3f(20.0f,-20.0f,20.0f);21. glVertex3f(20.0f,20.0f,20.0f);22. glVertex3f(-20.0f,20.0f,20.0f);23. glEnd();24. 25. 渲染一下:效果还不错!碰撞检测之前也实现过,在粒子系统里面加检测函数就Ok了.cppview plaincopy1. voidParticalSystem:checkBump(floatx1,floatx2,floaty1,floaty2)2. 3. for(vector:iteratoriter=particles.begin();iter!=particles.end();iter+)4. 5. if(iter-position.x-iter-sizeposition.x+iter-sizex2)iter-velocity.x=-iter-velocity.x;6. if(iter-position.y-iter-sizeposition.y+iter-sizey2)iter-velocity.y=-iter-velocity.y;7. 8. cppview plaincopy1. voidParticalSystem:checkBump(floatx1,floatx2,floaty1,floaty2)2. 3. for(vector:iteratoriter=particles.begin();iter!=particles.end();iter+)4. 5. if(iter-position.x-iter-sizeposition.x+iter-sizex2)iter-velocity.x=-iter-velocity.x;6. if(iter-position.y-iter-sizeposition.y+iter-sizey2)iter-velocity.y=-iter-velocity.y;7. 8

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论