OpenGL烟花粒子系统(含源码)

   烟花粒子系统是一种基于MFC对话框下的操作,主要是运用了OpenGL库函数。OpenGL是一个功能强大的开放图元库,用户可以很方便地开发所需要地有多种特殊视觉(如光照,纹理,透明,阴影)的三维图形,烟花粒子系统就是在该库函数下的产物,要想运行烟花粒子系统必须在VC6.0环境下安装OpenGL压缩包以及fmod压缩包。它主要通过运用粒子纹理映射,使烟花产生不同的爆炸效果,给看者一种视觉的享受,在该系统中还添加了爆炸的音乐,使烟花更加像真实存在的。为了方便用户操作,我们还设计了是否全屏显示的提示,便于用户自己选择怎样显示。

   

    我们知道了烟花粒子系统是通过纹理映射来实现烟花的爆炸,在爆炸过程中,我们还添加了七种烟花的爆炸效果,使得烟花更加的逼真好看。就烟花爆炸时的形状我们又载入了四种不同形状的位图,使得烟花爆炸时,姿态更完美绚丽。在烟花爆炸显示的时候,我们也做了一个小小的提示,用户可以根据自己的喜好选择所要播放烟花屏幕的形态,是全屏还是小屏。基于以上思路我们就一步步完成了烟花粒子系统。

    在以上讨论之后,我们对OpenGL烟花例子系统的具体功能有了一些认识。OpenGL 是一个功能强大的开放图元库,用户可以很方便地开发所需要地有多种特殊视觉(如光照,纹理,透明,阴影)的三维图形,与软件平台无关的三维图形软件包,可以运行多种窗口系统之上。

OpenGL:

包括115个基本函数

函数以gl开头

例:glColor3f(), glTranslate3f().   完成图元的定义、几何变换、投影等功能

VC6.0上配置OpenGL:

1.几个.dll文件 放入 C:\WINDOWS\system32

2.GL文件夹 放入 X:\Program Files\Microsoft Visual Studio\VC98\Include

3.几个 .lib 文件 放入 X:\Program Files\Microsoft Visual Studio\VC98\Lib

4.ProjectàSettings LINK标签

Object/Library Modules选项 (kernel.32)增加

                OpenGL32.lib  GLu32.lib  GLaux.lib  Glut32.lib 

 然后单击”OK”按钮

5.在程序前,需添加头文件:

   #include <GL/glut.h>

VC6.0平台编写OpenGL程序:

本课题是基于GLUT来编写OpenGL程序

利用如下步骤新建一个程序:

点击菜单“ File” à “New” à Projects à Win32 Console Application àempty project 

Project | Add to Project | New ,然后选择“C++ Source File

在出现的页面中编写编辑代码

     OpenGL包含图元生成、投影、光照、光栅化等图形显示功能所需的过程。就该系统做出如下的分析。框架界面:因为人们的喜好不同,为了满足不同人的喜好,烟花粒子系统在显示于主界面时,是否全屏显示因人而异,我们就对显示界面做了一个是否是全屏的提示,以方便用户的选择。


加载音乐:加载音乐是为了使烟花爆炸时的效果更形象,通过所加的音乐让人们看了后有种身临其境的感觉。加载音乐的方法就是在粒子系统中载入fmod声音库函数,通过函数CreateSound()BindSound()InitSound()来实现音乐的播放。

2.2烟花粒子设计

在粒子设计方面,每个粒子的生命是整个系统的关键,为了保证烟花爆炸会一直发生,就必须对粒子的设计做详细的描述。

尽管我们知道一个完美的粒子设计对一个烟花系统的成功有多大的意义,但是以现在我们的水平来看,想要做到美观、流畅是很不容易的,因为我们现在学的知识、水平有限,像纹理映射啊、监粒子系统啊什么的我们根本就一无所知,也不知道那是什么东西,不知道什么条件下才去用什么样的东西,但是我们并没有因此放弃,我们相互鼓励,不到最后一刻决不放弃。有了这样的干劲,我们开始去网上、图书馆查资料,尽我们所知道的各种途径去获取与OpenGL粒子有关的各种知识,我们的努力没有白费,终于在几天之后,对于做出一个什么样的烟花有了大致的想法,有了一个不太清楚的轮廓,我们就大致把做成什么样的烟花、烟花爆炸时有什么样的效果设想了一下。

通过粒子数据结构给粒子在三维空间中的位置、速度、上一个节点、下一个节点、尾巴的加速度进行了描述。还对粒子的颜色、寿命、衰减速度、粒子大小、是否有尾巴、尾巴增加速度,清晰的概括出来,指引着下面程序的添加,使整个烟花系统很明朗。

粒子链表的构建使得粒子在燃放过程中,源源不断的出现,当粒子的生命减少到小于0时,粒子死亡,然后通过粒子链表的构建使用void AddParticle(Particle ex) 函数,增加新的粒子,并对增加的粒子进行一切属性的赋值。                                 

2.3烟花粒子操作

虽然在上面OpenGL功能分析以及烟花粒子设计中,把一些问题都说了,但是似乎还是有点不清楚,所以又对粒子做了一些操作以便使我们的思路更清晰。

如果只是单纯的粒子,而不加对它进行修饰,它也无非就是一些散乱的粒子,没有什么价值所在,更不会像烟花那样出现绚烂多姿的形态和五彩的色彩,吸引人们的眼球,所以我们就对这些纯粹的粒子做了一些修饰。在粒子的程序中加入了一些爆炸效果,使得烟花粒子看起来更加形象,在粒子爆炸效果中粒子的运动方向都是随机的,粒子的大小也需要自己添加,粒子是否是爆炸粒子,粒子爆炸时有没有产生爆炸效果、以及粒子爆炸时有没有尾巴,都在爆炸效果中有清晰的代码。这个程序系统中总共添加了七种爆炸效果,每种爆炸效果中粒子的属性多多少少都有些改变,这就使得烟花爆炸时看起来更加真实。

                      第3章 功能实现 

在以上讨论之后,我们对OpenGL烟花例子系统的具体功能做出如下的分析。框架界面:因为人们的喜好不同,为了满足不同人的喜好,烟花粒子系统在显示于主界面时,是否全屏显示因人而异,我们就对显示界面做了一个是否是全屏的提示,以方

便用户的选择。音乐的加入主要是想给人们一种更加真实的感觉,如身临其境。

3.1 框架界面与加载音乐

 3.1.1框架界面

按照我们之前的思路已经把整个框架给描绘出来了,就差实际去动手做了。可以先创建一个框架。我们使用的是MFC。MFC是Win API与C++的结合。API,即微软提供的Windows下应用程序的编程语言接口,是一种软件编程的规范,但不是一种程序开发语言本身,可以允许用户使用各种各样的第三方的编程语言来进行对Windows下应用程序的开发,使这些被开发出来的应用程序能在Windows下运行,编程语言函数本质上全部源于API,因此用它们开发出来的应用程序都能工作在Windows的消息机制和绘图里,遵守Windows作为一个操作系统的内部实现,这其实也是一种必要。框架界面:因为人们的喜好不同,为了满足不同人的喜好,烟花粒子系统在显示于主界面时,是否全屏显示因人而异,我们就对显示界面做了一个是否是全屏的提示,以方便用户选择。

包含头文件:写下代码的前4行,它们包括了我们使用的每个库文件的头文件。如下所示:

#include <windows.h>        // Windows的头文件,因为这是Windows OS上的OpenGL

#include <gl\gl.h>          // OpenGL32库的头文件,这是OpenGL核心

#include <gl\glu.h>// GLu32库的头文件,这是OpenGL的实用库

#include <gl\glaux.h>       // GLaux库的头文件,用于管理OpenGL窗口

4、写下一些全局变量:将这些变量设置为全局变量是因为我们需要在程序中的多个地方访问这些变量。

HGLRC hRC=NULL;        // 永久着色描述表

HDC hDC=NULL;         // GDI设备描述表

HWND hWnd=NULL;   // 保存我们的窗口句柄

HINSTANCE hInstance;   // 保存程序的实例

 

boolkeys[256];      // 用于键盘按键的数组,用于保存键盘的状态

boolactive=TRUE;           // 窗口的活动标志,缺省为TRUE

boolfullscreen=TRUE;       // 全屏标志缺省设定成全屏模式,提示用户选择窗口模式

5、定义ReSizeGLScene函数:下面的函数发生在窗口大小变化时,其函数的作用是为了在窗口大小改变时,我们的三维场景也能作相应的调整

6、GLvoid ReSizeGLScene(GLsizei width, GLsizei height)

// 重新调整OpenGL 窗口,初始化时窗口大小也会变化一次

{

    if (height==0)  //防止被0除,看后面的(GLfloat)width/(GLfloat)height

    {

        height=1;   // 让高度为1

    }

    glViewport(0,0,width,height);       // 重置视口,完成程序后试着改变参数

    glMatrixMode(GL_PROJECTION);    // 选择投影矩阵,下面的改变都针对投影矩阵

    glLoadIdentity();   // 将投影矩阵重置为单位矩阵

    // 计算窗口的宽高比,用于设置透视投影

    gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

    glMatrixMode(GL_MODELVIEW); // 选择模型矩阵,后面的操作都针对模型视图矩阵

    glLoadIdentity();   //将模型视图矩阵重置为单位矩阵

}

Ok,上面的代码比较难懂,这里解释一下OpenGL的状态机概念,OpenGL的设置都像一个开关,开启了之后或者设置了之后,后面的程序都要受到该设置的影响,glMatrixMode(GL_PROJECTION);是用于设置透视效果的,如果后面没有glMatrixMode(GL_MODELVIEW);那么有可能图形就画不出来了。另一个概念是透视投影(远处的物体小,近处的物体大),其实还有一种是正交投影(远近一个样),看下面的图:


在我们的代码中fovy被设置为45aspect被设置(GLfloat)width/(GLfloat)height,透视图跟我们拍照的原理相似,远处的物体成像小,近处的成像大,而在这个锥体外的物体是不能成像的。

6、定义初始化函数InitGL这个函数主要用于初始化的工作。

int InitGL(GLvoid)  // 所有OpenGL的初始设置

{

    glShadeModel(GL_SMOOTH); // 启动平滑着色,如果设置为GL_FLAT,则不平滑过渡

    glClearColor(0.0f, 0.0f, 0.0f, 0.5f);   // 清除颜色缓存的颜色为黑色,也就是背景色

    glClearDepth(1.0f);//使用1.0来清除深度缓存中的值

    glEnable(GL_DEPTH_TEST); // 启动深度检测

    glDepthFunc(GL_LEQUAL);// 深度检测的类型

    return TRUE;

}

这里的一个主要概念是缓存,我们都知道屏幕显示的方案为双缓存机制,也就是先绘制到后台缓存,然后通过缓存拷贝一次性的显示出来,这样可以防止闪烁。帧缓存可以包括颜色缓存、深度缓存等。颜色缓存就是保存了每个像素的颜色RGB三个值,而深度缓存就是保存了每个像素的Z值。这里要说明一下深度检测的作用了:假如我们有两个物体AB,从你的眼光看去,加入A在某个像素上能够遮挡住B的,也就是A在某像素点的Z值比BZ值小(Z轴是从屏幕朝外的)。但是你如果不启动深度检测,哪么如果先画A后画

  • 10
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百事悠弦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值