APP下载

基于OpenGL的雪景视景仿真设计与实现

2014-02-08余久久傅廷亮张佑生

实验室研究与探索 2014年9期
关键词:视景雪景积雪

余久久, 傅廷亮, 张佑生

(安徽三联学院 a. 计算机科学与技术系; b. 信息与通信技术系, 安徽 合肥 230601)

0 引 言

研究天气变化对城市交通的影响具有重要意义。通过计算机仿真手段模拟出极为逼真的各种天气变化过程是一种虚拟现实技术,对于指导自然环境下开展防灾减灾工作起到重要作用。因为无需“身临其境”就能有效解决人类与自然界直接交互性的要求,所以在气象研究领域以及其它领域(航天航海、煤矿勘测等)具有广泛的应用前景。

本文采用虚拟现实技术完成对下雪天气中的雪景视景模拟过程,在Visual C++6.0平台下通过基于OpenGL图形编程技术予以设计并实现。

1 相关技术简介

1.1 虚拟现实技术与视景仿真

虚拟现实技术是指利用信息技术手段构造出一个虚拟的环境,用户能够与这个环境交互,从而获得身临其境的感觉[1]。视景仿真是虚拟现实技术重要的表现形式,使用户产生身临其境感觉的交互式仿真环境,实现出用户与该环境直接进行自然交互[2]。

1.2 OpenGL简介及功能

OpenGL是一个专业的绘画软件工具,是行业领域中最为广泛接纳的2D/3D图形API,适用于广泛的计算机仿真环境。具有建模、变换、颜色模式设置、光照和材质设置、纹理映射、位图显示和图像增强、双缓存动画等诸多功能[3]。作为图形硬件的一种软件接口,其严格按照计算机图形学原理设计而成,符合视觉与光学原理,适合于可视化仿真系统的开发与设计工具,在计算机上把视景对象用图形方式表达,通过光照处理表达出物体的三维特性,提供对图像数据的使用方法,并把图像数据定义为纹理与图形方法结合在一起生成相应视景图像以增强效果[4]。

2 开发环境与总体设计步骤

2.1 开发环境说明

程序的开发平台选用Visual C++6.0,Windows环境下通过win32控制台采用Windows图形图像编程方法,完成相关图形的绘制以及动态效果的实现。该程序需要较强的动画效果,相关图像连续帧至少要达到30fps,否则就要会使天气视景的效果变化不真实,所以要求比较高的实时响应[5]。在Windows编程中采用消息发送机制,不仅对屏幕的响应比较迅速,而且可以采用很多种方式实现动画的效果。设计人员每次使用不同图像重复地对显示器进行刷新,采用规范的Windows事件模型,能够在WM_PAINT消息处理程序中完成所有的绘制(或渲染)操作。每当需要刷新窗口操作,都会产生下一帧。基于此,在该程序中只需在Windows编程中的main函数中加入多个函数调用就可以达到快速描绘每一帧的目的。鉴于Windows 图形图像编程方法中采用OpenGL绘图工具中所提供的各种图像函数对三维图形的操作与实现简便,灵活,并且提供了很多对三维图形(实物)的绘制方式:例如,网格线绘图方式(wire-frame)绘制三维物体的网格轮廓线;光滑消隐绘图方式(smooth-shade)完成对实物进行消隐按光照渲染着色的过程,并进行光滑处理来接近现实;大气环境效果方式(atmosphere-effects)实现在三维视景中加入一些大气环境效果(如云、雾、烟因素等);运动模糊的绘图方式(motion-blurred)完成对模拟实物运动时人肉眼的感官现象等。OpenGL所提供的函数库能够较为逼真的模拟出比较复杂的三维实物或自然景观,具有从多个角度完成对三维实物或自然景观的特殊效果处理方式,所以在本文中选择它作为工具模拟雪景视景的原因。

2.2 三维图形视景仿真设计步骤

(1) 根据基本图形单元(点、线、多边形、位图、图像等)建立相应实景模型,如本文中飘扬的雪花。并且对所建立的模型进行数学描述。

(2) 把要模拟的实景模型置于三维空间中的合适的位置,通过设置最佳视点(viewpoint)来观察相应的视景。

(3) 根据应用需求计算出模型中所含物体的色彩,同时确定光照条件、纹理粘贴方式等。

(4) 把实景模型的数学描述及其色彩信息转换至计算机屏幕上的象素,即光栅化过程。

在这些步骤的执行过程中,利用OpenGL执行自动消隐处理等等一些其它操作。除此之外,实景光栅化之后在被送入帧缓冲器之前还可以根据需要对象素数据进行操作。

根据以上步骤,在程序主函数中所使用到的重要的是四个基本绘制图元函数及功能分别是:

void SetupRC();//用于图形界面初始化操作,常用来设置实景的渲染状态。

void RenderScene();//三维图像显示响应函数。

void init();//初始化操作函数,可以把设置实景的背景颜色或坐标系统的函数置于该函数中。

void glutReshapeFunc(); //回调函数,用来处理窗口变化的消息,如改变后窗口的宽度与高度。

3 雪景视景的OpenGL的设计与实现

3.1 设计思路描述

首先,确定景观视图。例如景观所在窗口大小,观测点的位置,景观背景的颜色设置、裁减空间等。选择在OpenGL中的void init(void)函数中主要完成一些具体初始化操作。如视图初始化,地面的网格,雪花下落的位置及速度,可能需要用到的光照的灯光位置等。

其次,调用OpenGL中void RenderScene()函数绘制相关图形。本文中通过调用void flake(void)绘制雪花图形,设置本程序运行一次将产生几千片雪花。雪花在飘扬中,根据物体运动方程修改其位置。同时判断雪花是否已经掉落到地面上,如果是,就形成积雪效果,并且产生新的雪花,满足雪花飘扬的视窗内一直有几千片左右片雪花在飘扬。当雪花掉落到地面上之后判断其飘落的位置,同时增加落点的高度。

最后,当改变窗口的大小时,及时修改景观窗口对应的比例,否则会导致所绘制的雪花变形。本文采用函数void ReSize( int new_x, int new_y )较好解决了此问题。当窗口最大化时,雪花不会变形以及飘落的相对位置也不会发生变化。

3.2 雪花飘扬情景的模拟

(1) 雪花可以有很多种方法进行绘制模拟。例如黑点、方点、圆球等,或直接用小方框产生。为达到逼真的仿真效果,本文用正方形表示雪花图案,将雪花随机旋转后,再把真实的雪花图片贴在图上,同时将背景正方形做透明处理,这样达到了真实的效果。这也是气象视景仿真领域中模拟雨水、雪花、冰雹、烟尘等颗粒系统常用的方法。图1为由雪花飘落的情境通过选择在白色的背景落下黑色的小方块的模拟视图(可以通过设置一个茶壶来确定观察者视点)。

图1 黑色的小方块的模拟视图

(2) 增加光照和明暗处理与雾化效果,粘贴上真实的雪花图片。设置背景为黑色的效果,表示黑色的天空飘落着白色的雪花,再现真实的大雪纷飞效果。图2与图3分别为未添加与已添加雾化效果与雪花图片、并设置背景模拟图。

图2 未添加效果的雪花飘扬模拟视图

图3 已添加效果的雪花飘扬模拟视图

在Visual C++6.0平台下使用OpenGL编程模拟出雪花飘扬视景,主要代码及注释(不包括头文件)如下:

void flake(void) //绘制模拟雪花的小方块

{::glBegin(GL_QUADS); //正方形

glNormal3f(0.0f,0.0f,1.0f); //法向量定义

::glVertex3f(-FLAKE_SIZE,-FLAKE_SIZE,0);

glTexCoord2f(1.0f,0.0f );

::glVertex3f(FLAKE_SIZE,-FLAKE_SIZE,0);

glTexCoord2f(1.0f,1.0f );::glVertex3f(FLAKE_SIZE,FLAKE_SIZE,0);

glTexCoord2f(0.0f,1.0f );::glVertex3f(-FLAKE_SIZE,FLAKE_SIZE,0);

::glEnd();}

void MakeTextureFromRes(UINT res_id,GLuint tex_id) //贴图

{……//贴上雪花图片,自定义雪花大小、形状等属性,代码略}

void init(void) //初始化操作

{LoadTexture();

::glEnable( GL_TEXTURE_2D );

theFlake=::glGenLists(1);

::glNewList(theFlake,GL_COMPILE);

::flake(); ::glEndList();

::glMatrixMode(GL_VIEWPORT); //确定视点

::glLoadIdentity();

::glViewport(0,0,600,600); //设置用户观测口

::glClearColor(0,0,0,1);

::glColor3f(1,1,1); //设置背景颜色为黑色

::glShadeModel(GL_SMOOTH); //清除图片毛刺

GLfloat lmambient[]={1.0f,1.0f,1.0f,1.0f};

::glLightModelfv(GL_LIGHT_MODEL_AMBIENT,lmambient);

::glEnable( GL_BLEND );

::srand( (unsigned)time( NULL ) );

for(int i=0;i

{p[i].alive=TRUE;

p[i].x=rand()%GROUND_LENGTH_X;//int-->float

p[i].z=rand()%GROUND_LENGTH_Z;//int-->float

p[i].y=CLOUD_DISTANCE_TO_THE_GROUND+rand()%CLOUD_THICK;//int-->float

p[i].vx=rand()%30-15.0f;//rand()%10; //可以增加X轴方向的风向如果需要的话

p[i].vy=rand()%30+3.0f; //雪花以不同飘落速度在垂直方向下落

p[i].vz=rand()%30-15.0f;//rand()%10;// 可以增加Z轴方向的风向如果需要的话

p[i].rx=rand()%180; p[i].ry=rand()%180; p[i].rz=rand()%180;

p[i].degree=rand()%180+10.0f;//避免雪花飘落时不旋转

p[i].rotate_speed=rand()%50+5.0f;}

//绘制飘落的雪花

::glBlendFunc( GL_DST_ALPHA,GL_ONE );

::glBindTexture( GL_TEXTURE_2D,flake_texture ); //貼上雪花的纹理

for(int i=0;i

{ if(p[i].alive=True) // 判断雪花是否飘落在地面上

{p[i].y-=p[i].vy*SNOW_SPEED_TIMES;

p[i].x+=p[i].vx; p[i].z+=p[i].vz;

p[i].degree+=p[i].rotate_speed; //转动的角度

float mesh_center_height=

(ground[x_index][z_index][1]+ ground[x_index+1][z_index][1]+ground[x_index][z_index+1][1]+ground[x_index+1][z_index+1][1])*.25f;

if(p[i].y<300&&p[i].y>mesh_center_height)//假定当积雪层低于300,高度才可视

{::glPushMatrix();

::glTranslated(p[i].x,p[i].y,p[i].z);

::glRotated(p[i].degree,p[i].rx,p[i].ry,p[i].rz);

::glCallList(::theFlake);

::glPopMatrix();}

if(p[i].y>mesh_center_height); //大多数雪花仍然在飘扬

else // 雪花落地情境

{float incre_x1= (p[i].x-ground[x_index][z_index][0])/ GROUND_POINT_GAP*SNOW_THICK_PER_FLAKE;

float incre_x2=(ground[x_index+1][z_index][0]-p[i].x) /GROUND_POINT_GAP*SNOW_THICK_PER_FLAKE;

float incre_z1=(p[i].z-ground[x_index][z_index][2])/ GROUND_POINT_GAP*SNOW_THICK_PER_FLAKE;

floatincre_z2=(ground[x_index][z_index+1][2]-p[i].z)/ GROUND_POINT_GAP*SNOW_THICK_PER_FLAKE; ground[x_index][z_index][1]+=(INCRE_TIMES*(incre_x1+incre_z1));

ground[x_index+1][z_index][1]+=(INCRE_TIMES*(incre_x2+incre_z1));

ground[x_index][z_index+1][1]+=(INCRE_TIMES*(incre_x1+incre_z2));

ground[x_index+1][z_index+1][1]+=(INCRE_TIMES*(incre_x2+incre_z2)); p[i].alive=FALSE;}}

else { p[i].alive=FALSE;} }

else{ // 重新产生雪花,代码略

p[i].vx=rand()%30-15.0f;

p[i].vy=rand()%30+5.0f; //雪花以不同飘落速度在垂直方向下落p[i].vz=rand()%30-15.0f;}}

::glPopMatrix(); ::glFlush();

::SwapBuffers(::wglGetCurrentDC());}

3.3 地平面上模拟积雪效果

计算机模拟实景与真实自然景观的实际形成过程往往存在差异。例如冬季里大雪纷飞,一段时间后地面会产生厚厚积雪。但是OpenGL自带的程序大多没有对加入对积雪效果的实现。无论是否绘制出地面,即使地面上初始时已经有雪花,但是雪花飘落时地面时雪片堆积高度始终不变,即无法显示出实际中的“积雪”效果。产生积雪效果也是雪景视景组成中的一部分,通常的模拟方法所存在的难度主要是如何确定雪花飘落时的坐标位置,雪花飘落到地面上的高度变化等。本文采用的方法是把地面以X-Z平面划分成若干网格,当每一片雪花飘落到地面上时判断其落在哪一个网格内。同时对雪花飘落到的所在网格的高度作自增操作,把每个网格分成两个三角形,对1帧的地面进行三角形的拟合过程。这样整个地面实际上是由三角形铺满的,同时在每个三角形上贴上地面的纹理的贴图,并增加纹理效果。所以就有了当雪花覆盖时地面上所产生积雪的凹凸不平的效果。图4为采用了三角形拟合地面所产生的积雪效果图。主要功能代码及注释如下:

//构造大地上产生积雪效果的程序段:

for(x_index=0;x_index

for(z_index=0;z_index

{ground[x_index][z_index][0]=(float)x_index*GROUND_POINT_GAP; //构造X地平面

ground[x_index][z_index][2]=(float)z_index*GROUND_POINT_GAP; //构造Z地平面

ground[x_index][z_index][5]=0.0f;}}}

void caculate_ground_normal() //采用三角形铺满地面构造大地

{GLfloat v[6][3],n[6][3];

for(x_index=1;x_index

for(z_index=1;z_index

{v[0][0]=ground[x_index][z_index][0]-ground[x_index][z_index-1][0];

……//用同样的方法定义出v [0][1]至v[5][2] }}

void ReSize( int new_x, int new_y ) //调整图像界面剪裁窗口

{if ( new_y == 0 ) new_y = 1;

::glMatrixMode(GL_VIEWPORT);

::glViewport( 0, 0, new_x, new_y ); //重置当前观测点

::glMatrixMode( GL_PROJECTION );

::glLoadIdentity();

ratio=( GLfloat ) new_x / ( GLfloat ) new_y;

gluPerspective(eye_angle,ratio,50.0f,GROUND_LENGTH_Z*3.5f );

glMatrixMode( GL_MODELVIEW );//选择观测模型视角矩阵

glLoadIdentity();}

图4 三角形拟合地面所产生的积雪效果图

3.4 手动控制观测视角及大雪覆盖效果的渲染

为了使观测者通过计算机屏幕能从多个方向、多角度灵活方便地观察下雪的效果,同时也为了保证雪景视景模拟的高度逼真性,需要采用键盘控制改变观测视角。本文以设置一个观察壶作为观测视角方位变化的准心,通过在代码中加入了相应的键盘操作命令(函数)就可以实现用户手动控制控制键盘完成准心方位变化来带动观测方位变化的目的。程序运行一段时间后,同样以雪花沉积相对观察壶的高度来衬托出积雪覆盖的效果。图5与图6分别为通过键盘调整观察壶角度的视景图以及程序运行了一段时间后大雪快要覆盖观察壶情境所渲染出的积雪效果图。主要的实现代码及注释如下:

GLuint theFlake;

::particle p[PARTICLE_NUM];

GLfloat ground[GROUND_POINT_NUM_X][GROUND_POINT_NUM_Z][6]; //绘制带法向量的大地网格点

//……初始化设置,自定义OpenGL像素区域的属性,代码略;

int pixelformat_index;

if ( ( pixelformat_index = ChoosePixelFormat( hdc, & pfd ) ) == 0 )return false;

if ( SetPixelFormat( hdc, pixelformat_index, & pfd ) == false )return false;

return true;}

void RenderScene()//具体的画图

{ ::glMatrixMode(GL_PROJECTION);

::glLoadIdentity();

::gluPerspective(eye_angle,ratio,50.0f,GROUND_LENGTH_Z*3.5f); //确立观测者视点

::glMatrixMode(GL_MODELVIEW);

::glPushMatrix();

::gluLookAt(GROUND_LENGTH_X*0.5f+GROUND_LENGTH_X*1.6f*cos(angle),eye_height,GROUND_LENGTH_Z*0.5f+GROUND_LENGTH_X*1.6f*sin(angle),

GROUND_LENGTH_X*0.5f,0,GROUND_LENGTH_Z*0.5f,0,1,0); //设置窗口剪裁区

……//绘制地面过程,代码略

caculate_ground_normal(); //计算地面上点的法向量

glBindTexture( GL_TEXTURE_2D,ground_texture ); //粘貼纹理效果

for(x_index=0;x_index

{ ……//绘制出x方向与z方向地面上的网格,代码略}

::glEnd();

::glBegin(GL_LINES); //划线作为标准线,坐标线

::glVertex3f(0,0,0);

::glVertex3f(GROUND_LENGTH_X*1.2f,0,0); //X

::glVertex3f(0,0,0);

::glVertex3f(0,GROUND_LENGTH_Z*1.2f,0,0); //Z

::glVertex3f(0,0,0);

::glEnd();

::glBindTexture( GL_TEXTURE_2D,teapot_texture );

::glPushMatrix();

::glTranslated(GROUND_LENGTH_X*0.5f,46,GROUND_LENGTH_Z*0.5f); //转动方位

glutSolidTeapot(60.0f); //设置一个观察壶渲染大雪覆盖效果

::glPopMatrix();

图5 以观测壶为准心的雪景方位效果图

图6 大雪覆盖观测壶所衬托出的积雪效果图

4 讨 论

本文尝试在Windows环境下利用OpenGL软件模拟并实现出一系列简单的雪景视景图,包括雪花飘扬、地面积雪效果以及观测视角转换效果图。虽然还不能完全真实地再现整个下雪过程的全景效果,但是已对雪景构成数据可视化且对其所包含基本要素完成了初步仿真过程,把对传统的通过听觉获取气象信息转化为通过视觉获取,可以应用于现代天气预报技术及相关气象变化仿真软件的开发中。当然,如果在模拟天气变化的各种图像中加入真实的背景图案、声音效果等,会更加贴切自然。在实际的天气变化过程中,往往还有多种气象因素(景观)并存或混合现象,如雨雪交加、电闪雷鸣、风起云涌等,这就要求对气象视景的模拟过程还要考虑天气变化的多样性、交互性与实时性问题,以及受到实际自然环境的影响。因此这些将成为未来下一步的研究工作。

5 结 语

本文在Visual C++6.0平台下使用OpenGL软件通过对粒子飘落过程进行设计,结合雪花函数与贴图模拟处雪花飘扬情景;将大地以X-Z平面形式划分成若干网格,每个网格分成两个三角形,对每一帧地面进行三角形的拟合过程模拟地面产生积雪现象;通过设置观察壶为准心辅以键盘操作命令实现图像观测方位变化的效果。从而较好完成对单一环境下的雪景的模拟,达到了仿真下雪情境的要求。未来还将就实际中多种天气混合(如雨雪交加等)情境进行仿真设计,从而更好地把计算机仿真技术运用于对天气视景变化的研究领域中。

[1] 李姝博. 虚拟现实技术在职业教育中应用的理论研究[J]. 辽宁高职学报,2013,15(7):13-15.

LI Shu-bo.Theoretical Study on Application of Virtual Reality Technology in Vocational Education[J].Liaoning Higher Vocational Technical Institute Journal, 2013,15(7):13-15.

[2] 陈国栋.视景仿真技术在天气预报中的应用研究[J].福建电脑, 2006(12):69.

CHEN Guo-dong. Visual simulation technology application studies in weather forecasting[J]. Fujian Computer, 2006(12):69.

[3] 宋晓伟,唐 涛. 列车运控系统视景仿真的设计与实现[J].系统仿真学报,2007,19(16):3864-3867.

SONG Xiao-wei,Tang Tao.Design and Implementation of Visual Simulation in Trains control System[J].Journal of System Simulation,2007,19(16):3864-3867.

[4] 郭慧玲. 基于OpenGL的三维真实感地形模拟的实现[J].科技创新与应用,2012(11):44.

GUO Hui-ling. The realization of the 3 d realistic terrain simulation based on OpenGL[J].Science and technology innovation and application, 2012,11:44.

[5] 干微微,谭喜堂,申朝旭. 基于OpenGL的沙尘暴天气仿真研究[J]. 机电一体化,2010,10:54-55.

GAN Wei-wei,TAN Xi-tang,SHEN Zhao-xu. Study on Simulation of Sandstorm Based on OpenGL[J].mechatronics,2010(10):54-55.

[6] 聂良兵,王培俊,潘 璇,等.三自由度运动平台的运动仿真及控制设计[J]. 机械与电子,2013(4):59-62.

NIE Liang-bing, WANG Pei-jun, PAN Xuan,etal. Movement Simulation and Control Design of 3-DOF Motion Platform[J].Machinery & Electronics, 2013(4):59-62.

[7] 虚拟现实[EB/OL].http://www.baidu.com/虚拟现实原理.html, 2012.

[8] 应用程序框架设计—基于Windows“事件驱动”模型[EB/OL].http://www.baidu.com/事件驱动模型.html, 2011.

[9] 廖宏刚,刘 荣. 基于OpenGL的三维真实感地形的实现[J]. 电子科技,2013,26(9):164-165.

LIAO Hong-gang, LIU Rong. Realization of 3D Real Terrain Based on OpenGL[J]. Electronic Science and Technology, 2013,26(9):164-165.

[10] 霍烁烁,刘艳冰,禄永旭 等.基于OpenGL的全景导游系统设计[J].无线电工程,2013,43(12):7-9.

HUO Shuo-shuo, Liu Yan-bing, LU Yong-xu,etal. Design of Panoramic Guide System Based on OpenGL[J].Radio Engineering of China, 2013,43(12):7-9.

[11] 刘巧红,单 贵,钱家乐.三维仿真场景构建及漫游系统实现[J].西华大学学报(自然科学版),2010,29(6):62-69.

LIU Qiao-hong, SHAN Gui, QIAN Jia-le.The Construction of 3D Simulation Scene and Implementation of Roam System[J].Journal of Xihua University(Natural Science Edition),2010,29(6):62-69.

[12] 陈玉军,张 旭.基于OpenGL的视景仿真系统中纹理的应用[J].中国制造业信息化,2012,41(7):62-64.

CHEN Yu-jun,ZHANG Xu. Application of Texture in the Scenery Simulation System Based on OpenGL[J]. China's manufacturing industry normalization, 2012,41(7):62-64.

[13] 高 颖,黄罗军,许志国,等. 基于OpenGL的某导弹视景仿真技术研究[J].兵工学报,2007,28(1):126-128.

GAO Ying, HUANG Luo-jun, XU Zhi-guo,etal. Designing and Implementing of a Missile's Visual Simulation System Based on OpenGL[J].Acta Armamentarii, 2007,28(1):126-128.

[14] 周 颖,严利鑫,吴 青, 等. 基于虚拟现实技术的典型动态交通场景的设计与实现[J].交通信息与安全,2013,31(1):129-132.

ZHOU Ying, YAN Li-xin, WU Qing etc. Design and Implementation of the Typical Dynamic Traffic Event with Virtual Reality Technology[J]. Journal of Transport Information and Safety, 2013,31(1):129-132.

[15] 李 宁,王立文,陈幕华.基于Vega的机场天气特效视景仿真研究[J].机床与液压,2008,36(10):170-173.

LI Ning, WANG Li-wen, CHEN Mu-hua. A Study of Visual Simulation for Weather Special Effects of Airport Based on Vega[J]. Machine Tool & Hydraulics, 2008,36(10):170-173.

·名人名言·

聪明的资质、内在的干劲、勤奋的工作态度和坚忍不拔的精神。这些都是科学研究成功所需的其他条件。

——贝费里奇

猜你喜欢

视景雪景积雪
虚拟现实技术在游戏设计中的应用及研究
我们
《雪景山水图轴》
《雪景寒林图》
《雪景山水图》
大粮积雪 谁解老将廉颇心
积雪
2000~2014年西藏高原积雪覆盖时空变化
雪夜遇熊
全回转拖轮运动建模与视景仿真