注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

ocean's blog

平常心——可以寂寞,但不允许空虚

 
 
 

日志

 
 

OpenGL模拟雨雪自然现象  

2009-05-30 14:10:00|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
模拟雨雪等自然现象,在计算机图形学中既是热点,也是难点。目前流行的做法是采用粒子系统来构建自然现象的产生、发展、消亡的过程模型,从而实现自然现象的模拟。

一、过程模型

    可视化建模技术一般分为两类:几何建模和行为建模。

    几何建模:表示物体的几何和形状,研究物体的拓扑结构;

    行为建模:描述物体的运动和行为。

    过程模型是将几何建模和行为建模统一起来,研究的是物理或生理的模型。

二、粒子系统

    粒子系统首先是在1983年由Reeves提出的。粒子系统是一种过程模型,它是利用各种计算过程生成模型中各个体素的建模技术。顾名思义,粒子系统就是由许多粒子构成,而这些粒子就是所谓的构成物体的简单体素。每个粒子有各自的属性,这些属性包括速度、运动方向、位置、颜色、透明度和生命周期等。具体到不同的应用,粒子可以具有不同的属性。粒子系统是不断进化的,首先,粒子由粒子源产生,它们初值由随机过程产生,随着时间的推移,系统中不断地加入新生的粒子,删除掉死亡的粒子,而系统中活着的粒子则不断随着生命期改变着自己的位置等属性,通过这样的过程来模拟许多自然现象。

    在粒子生命期的每一刻,都要完成以下五步工作: 

    1) 粒子源产生新粒子并赋予粒子初始的属性,然后加入到粒子系统中;

    2) 根据粒子的动态属性对粒子进行移动和变换,同时更粒子属性;

    3) 判断粒子的生命值;

    4) 删除那些已经超过其生命周期的粒子;

    5) 绘制并显示由有生命的粒子组成的图形。 

三、雨雪的模拟实现过程

定义粒子的结构体:

typedef struct Particle

{

    float v;                        //粒子的速度

    Position point;                 //粒子的位置坐标

    float dx,dy,dz;                 //x、y、z轴方向上的增量

    BOOL bTatus;                    //粒子的状态TRUE为粒子活否则为死)

    float a;                        //粒子的透明度alpha

    Particle *next,*prev;

PARTICLE;

1、初始化粒子InitParticle

    粒子的速度:由于雨雪是下落的过程,所以只考虑向下的速度,为简单起见,将下落看成匀速运动,速度设为常量。

    粒子的位置:粒子的初始坐标由随机过程产生

     x = (float)(rand()*(50.0/RAND_MAX)-25);

     y = 6;

     z = 0;

粒子的方向增量:     

    dx = 3;

    dy = - (float)v*(1 + rand()*(0.5/RAND_MAX)));    // 下落

    dz  =0;

    粒子初始总是具有生命的,bTatus = TRUE;

    粒子的透明度为1.

2、移动粒子MoveParticle

    移动粒子的时候,就是将粒子系统中所有具有生命的粒子的位置加上在各个方向上的偏移量,计算粒子的新的位置,并更新其他属性。

3、删除死亡的粒子DeleParticle

    通过判断bTatus标志量,删除粒子系统中死亡的例子。

4、绘制粒子DrawPartile

    绘制粒子是关键的一步。绘制粒子的时候涉及到纹理映射和融合技术,将雨、雪的纹理图片映射到表示粒子的矩形面片上,首先需要载入纹理,并进行纹理映射。

    glBegin(GL_QUADS);

    glTexCoord2f(0.0f, 0.0f);  

    glVertex3f(-1.0f*m_nPartSize, -1.0f*m_nPartSize,-0.0f);// 纹理和四边形的左下

    glTexCoord2f(1.0f, 0.0f);  

    glVertex3f( 1.0f*m_nPartSize, -1.0f*m_nPartSize,-0.0f);// 纹理和四边形的右下

    glTexCoord2f  (1.0f, 1.0f);  

    glVertex3f( 1.0f*m_nPartSize, 1.0f*m_nPartSize,-0.0f);// 纹理和四边形的右上

    glTexCoord2f(0.0f, 1.0f);  

    glVertex3f(-1.0f*m_nPartSize, 1.0f*m_nPartSize,-0.0f);// 纹理和四边形的左上

    glEnd();

其中m_nPartSize是粒子的尺寸大小。

    同时在绘制之前需要打开纹理映射开关和融合开关。

    glEnable(GL_TEXTURE_2D);                // 纹理映射

    glBlendFunc(GL_SRC_ALPHA, GL_ONE);      // 融合

    glEnable(GL_BLEND);

 

  评论这张
 
阅读(131)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018