我要发帖 回复

高级会员

30

主题

1299

积分

0

专家分

:

私信
发表时间 : 2007-10-17 01:09:02 | 浏览 : 5445    评论 : 16
本文讲述了利用基于OpenGL 图形标准的高级函数库OpenGVS实现在虚拟现实中下雨、下雪的特效。文中给出的代码适合OpenGL的软件,如vega等。
按照本文讲述的方法,读者根据自己的需要生成各自粒子特效。

最近VR访客

flytree2007 评论于2007-10-17 01:12:08

1


、引言
虚拟现实技术(Virtual Reality),又称灵境技术,是90年代为科学界和工程界所关注的技术。它的兴起,为人机交互界面的发展开创了新的研究领域;为智能工程的应用提供了新的界面工具;为各类工程的大规模的数据可视化提供了新的描述方法。这种技术的特点在于,计算机产生一种人为虚拟的环境,这种虚拟的环境是通过计算机图形构成的三度空问,或是把其它现实环境编制到计算机中去产生逼真的“虚拟环境” ,从而使得用户在视觉上产生一种沉浸于虚拟环境的感觉。
本文通过粒子系统,给虚拟现实应用添加下雨、下雪的特效,从来更加增加使用者的沉浸感。
二、OpenGVS开发包的特性
如果开发实时三维图形应用,OpenGVS是提供给开发者领先、成熟、方便的视景管理系统。OpenGVS是世界上第一个通用工作站平台的3D视景管理软件。OpenGVS是基于OpenGL 图形标准的高级函数库,可以被应用于所有图形平台标准。一旦你编好你的应用程序,它可以运行在从高端图形工作站到Pc的任何系统上。功能强大的3D SDK帮助你快速有效地制作3D产品。OpenGVS是一个开放的系统。它可以使开发者的应用使用任何软硬件平台上。高级面向对象的OpenGVS API。满足用户的各自项目的要求。诸如:模型、运动方程、灯光照明等。OpenGVS替用户完成底层的难度较大的3D图形工作。使用OpenGVS你只需用很少的几行代码就可编写一个完整的简单应用程序。不象vega软件,OpenGVS本身不带粒子系统。所以,用户如果想生成各种特效,需要自己通过编写OpenGL的粒子系统,然后集成到OpenGVS中。
三、在OpenGVS中集成OpenGL代码
由于OpenGVS是基于OpenGL图形标准的高级函数库,所以集成OpenGL代码是非常方面且有效的。
首先,我们可以先创建一个空的对象,并且把它加入到场景中。
GV_ Obd def; ,,/对象定义
GV_ObiinstV 象突
GV_ obd_open~y_name《 FX”,&def J
//创建一个空的对象定义
GV_ obd_close《def):
G、, bdjet_固f~calIback(def;show_gfx_fx):
/ 指定对象的图象回调函数
GV_ obd_set_drawing orde def;20000):
GV_ obijnstance(def,&inst l//对象实例化
G、, e¨jdd-9bject(scenei(nst} i/加入场景中
以上千℃码中,G bd efJ _x_callbac (de£sllow. )
这个调用是非常重要的。这个函数给对象指定图像回凋函
数show_gfx fx,我们就可以在回调函数中使用OpenGL代码来
实现自己想要的功能。例如:
static_nt show_gfx_ fx(GV_Obi inst,,void datajn)
0
GLint texture2d lighting,depthtest; |
GLfIoat tinewidth |
, 。(void)inst;
《void )datajr
/ 先保存系统OpenGL的设置 /
glGetIntegerv《GL_DEPTH TEST,&depthtest):
RAINDR0P— ELEMENTS;
//Retrieve current raindrop s speed
fCurrentSpeed :gafDropSpeed【nDropfndex】:
//Decrease height
pglfDropEIement[4】4-=fCurrentSpeed:
pglfDropElement【1 O】4-=fCurrentSpeed:
//利用速度,改变当前位置
g~fDropSpeed【nDroplndex】4-=
DROP
_ACCELERAT10N://利用加速度改变速度
lf(pglfDropElement【4】<0.Of)
{
pglfDropElement【9】= pglfDropElement【3】= 一7O.0f
+ ((GLfloat)rand()/234.05f):
pglfDropElement【1 1】= pglfDropElement【5】= 一
70.Of 4- ((GLfIoat)rand()/234.05f):
pglfDropElementf4】= 1OO.Of一((GLfloat)(rand()))
/409.Of;
pglfDropElementf 1 O J=pglfDropElementf4 J一1.5f
g_afDropSpeed【nDroplndex】=INITIAL DROP_SPEED;
}//当雨点位置低于某一值时,重新设置其位置
}
}
static nt gfx_ draw_ .rain(GV bi obi,void datajn)
//显示下雨的图象回调函数
f
staticfloat acol【4】={1.0, 0,1.0,1.O)
(void)obi; /$ Not used at present /
gIDisable(GLJEXTURE_2D);
g!lnterleavedArrays(GL_C3FY3F,0,g__aglfRainDrops):
giDrawArrays(G INES 0,MAX_RAINDROPS }2);
gIEnable(GL FEXTURE D)
return 1:
}
3.下雪的函数
void h1itSnow()//初始化雪
{
int i:
if(fcreate_txr())//加载雪花纹理
{
return;
}
srand(GetTickCount()}:
for(i=O i<MAX_SN0W DROPS;i 4-)
{
Snowf_】l Texturelndex=rand()%3:
Snow【l】.x=(float)(rand()%200—1 00)
Snow⋯ .z=(float)(rand()%200—10O
Snow【i】.Y=1 OO.Of 4-(float)(rand()%25):
Snow¨】.xrot=Snow【l】.yrot:Snow【l】.zrot=O:
Snow【l】l Dspeed=0.05f$(rand()%1 O+2):
Snow【i】.Rspeed=0.1f (rand()%1O+2):
glGetlntegerv《GL_LiGHTIN &lighting)
glGetlntegerv《GL_TEXTURE_2D,&texture2d):
⋯ glGetFIoatv( GL_LINE_W IDTH。& linewidth
在这里输入OpenGL的代码 /
/$恢复系统OpenGL的设置}/
|f(depthtest>0)
glEnable(G EPTH TEST):
if(1ighting>0)
glEnable(GL_LIGHTING):
If(texture2d>0)
glEnable(GL_TEXTURE_2D):
glLineWidth f Jinewidth)
return G .SUCCESS;
)
四、实现雨、雪特效
1.下雨下雪的有关变量
#define MAX LOADSTRING 1 00
#define lMAX_ _RAINDROPS 3000 //控制雨点的数量
#define RAINDROP ELEM ENTS 1 2
#define RAINl AME OpenGVS IRAIN
#define SNOW NAME OpenGVS SNOW
#define Ml M AX_ SNOWDROPS 3000 //控制雪的数量
#define SNOW DR0P ELEMENTS 1 2
GLfloat g_aglfSnowDrops【MAX_SNOWDROPS $ SNOW—
DROP _ELEMENTS 1:
float g_ afSnowDropSpeed【MAX SNOWDROPS l:
const float INITIAL NOW PEED : 一0.•02f;
//控制雪的初始速度
const float SNO LACCELERATIONl 一0.003f:
//控制雪的加速度
GV Obd rain_
def =NULL;
GV- bi rainjnst=NULL;
GV bd snow5lef= NULL;
GV_ Obi snowjnst=NULL; •
//雨、雪的对象定义及实例句柄
GLfloat g_ aglfRainDrops【MAX RAIN DROPS
RAINDROP ELEMENTS】:
float g_ afDropSpeed【MAX_RAINDROPS
float INITIA!._DROP ED = 一 : _ SPE 0 02f
//控制雨点的初始速度
float DR0P ION = 一O 1f: _ACCELERAT
//控制雨点的加速度
float deltax = 0.25:
nt env』um =O://控制下雨、下雪或不下
int snow_ num = O:
#define TEXTUREC0UNT 3
char bmpfilelTEXTURECOUNT】=("Data/2.rgb , Da—
ta/3.rgb , Data/4.rgb )://雪的纹理图片
GV_Texture texture【TE×TURECOUNT】:
GLfioatyrot;//Y旋转
typedef struct TSnow
{
floatx.Y.z:
float xrot,yrot,zrot;
float Dspeed:
, float Rspeed;
nt Texturelndex;
lTSnow;
TSnow Snow MAX_ SNOWDROPSl:
2. 下雨的函数 -
void InitDrops《void J//初始化所有产生雨点的点
(
nt nDroplndex;
GLfloat pglfDropElement;
for(nDroplndex=0:nDropIndex<MAX_ RAINDROPS;
nDropIndex+ +)

/Calculate current raindrop s address
pglfDropElement= g_ aglfRainDrops nDroplndex
RAINDROP_ ELEM ENTS,
"
//lnitialize colors
pglfDropElement f 0】=O、65f;
pglfDropElement【1 l=o 65f;
pglfDropElement l 2】=0.65f;
pglfDropElement【6 l=0.65f;
pglfDropElement【7 l=0.65f;
pglfDropElement l 8】=0.65f;
//Initialize coordinates 3、4、
//10、11表示第二点坐标
//第一点的颜色
//第二点的颜色
5表示第一点坐标9、
PgIfDropElement[9l= pglfDropEIement[3]= --.70.O +
((GLfioat)rand()/234.05f) // 一70to 70
pglfDropElementl4】= 1OO.Of一(IGLfIoat)I randI)))/
409,Of; // ~1OtO 5O
pglfDropElement【1 1】= pglfDropElement【5】: ~70.Of
+ ((GLfloat)rand()/234.05f):// 一70 to 70
pglfDropElement[10】 pglfDropElement[4]一1.5f;
)
// Reset drop speeds;
for l nDroplndex O nDroplndex <lMAX_
RAINDROPS;nDroplndex+ +)
{
g_afDropSpeed【nDrol~Index】=INITIALj)ROP_SPEED:
//雨点初始速度
)
)
void AnimateDrops(void)//使雨点动起来
{
int n Droplndex;
GLfloat pglfDropElement:
float fCurrentSpeed;
for(nDroplndex= nDroplndex<MAX_ RAINDROPS;
nDroph1dex-i-+)
f
/Ca cqlate current raindrop。s address
pglfDropElement= g_ aglfRainDrops + nDrop【ndex %
flytree2007 评论于2007-10-17 01:13:26

2

}
)
Void AhimateSnowDrops(void)//使雪动起来
{
mt i
for(i=O:i<MAX_SNOW DROPS:i 4- 4-)
(
Snow⋯ .Y一=Snow⋯ .Dspeed;
|f(Snow⋯ .Y<0.0)
Snow【I】.Y=1 OO.Of+(float)(rand()%25):
Snow⋯ .xrot 4-:Snow⋯ .Rspeed;
Snowl_】l’vrot 4-:Snow⋯ .Rspeed;
Snow⋯ .zrot+=Snow【i】.Rspeed;
}
yrot 4- =0.2f;
}
static int gfx_ draw_.snow (GV bi obi,void data in)
//显示下雪的图像回调函数
{
int I_
staticfloat acolf4 J= (1.O, O,1.O,11.O}:
(void)obi;. / Not used at present /
gl】PushMatrix():
glDisable(GL_LIGHTING)
glDisable(GL OLOR MATERIAL):
for(i=O:i<MAX SNOW DR0PS l+ +)
{
glColor4fv(aco1):
glLoadIdentity():
glTranslatef(O.Of,一3O.Of,一1 5O.Of);
glRotatef(yrot,0.Of,1.Of,O.Of):
GV_txr_ set urrent(texture【Snow【i】l Texturelndex】):
glTranslatef(Snow⋯ .x,Snow⋯ .Y,Snow⋯ .z):
glRotatef(Snow⋯ .xrot, 0f,O.Of,0.Of);
glRotatef(Snow⋯ .yrot,0.Of,1.Of,O.Of);
gIRotatef(Snow⋯ .zrot,0.Of,0.Of,1.O
//雪花
glBegin(GL UADS):
glNormal3f(O.Of,1.O 0.0f):
glTexCoord2f(0.Of 0.Of):giVertex3f(1l Of,O.Of, 一
1.Of):
glTexCoord2f(1.0f, O.0f) glVertex3f( 1.O O.Of,
1.Of):
glTexCoord2f(1.Of, 1.Of): glVertex3f(一1.Of, O.Of,
1.Of):
glTexCoord2f(O.Of, 1.Of): glVertex3f(一 Of, 0.Of,
一1 Of):
glEnd():
GV_txr_set_current(NULL);
flytree2007 评论于2007-10-17 01:14:31

3

giEnable(GL上lGHTING):
glEnable(GL OLOR_MATERIAL)
giPopMatriX()=
return 1:
4.辅助功能
在虚拟场景中实现下雨、下雪的特效,我们还需要修改
场景中的三维模型,当下雨的时候,把场景中的三维模型的纹
理切换成雨天的纹理;同样的道理,当下雪的时候,把场景中
的三维模型的纹理切换成雪天的纹理。这样,我们就实现了更
加逼真的虚拟现实世界了。
obuil 评论于2007-10-17 08:57:13
支持一下  建议多使用论坛的功能:[code] 代码内容 [/code]
UE4   |   虚幻引擎   |   Unity VR    |    Hololens
xuyu 评论于2007-10-17 10:34:17
太感谢了!
force8008 评论于2007-10-29 13:24:20
呵呵,还需要视点矩阵转换,只让雨雪出现在基于视点的范围的包络合内,要不然运动起来就不对了。
机器余专家组 认证企业会员 评论于2007-11-11 17:08:23
谢谢.楼主
adm0117 评论于2007-11-26 22:33:14
谢谢,顶一下
kknasa 评论于2007-12-4 15:18:39
谢谢,正用得到呢
kknasa 评论于2007-12-4 15:32:36
谢谢,正用得到呢
gqd2006 评论于2008-4-15 08:46:55
初学者,学习学习
wygwjw 评论于2008-5-10 16:54:20

谢谢

佩服!!!
lanxiaodi 评论于2008-6-12 09:20:09
先收下了,感谢LZ!!
小黑 评论于2008-6-14 15:22:29
谢谢了啊
flytree2007 评论于2008-6-29 22:49:29

谁把代码调试出来了?

发个程序上来。可是有奖励的啊。
Holy_Puck 评论于2009-5-4 12:28:30
好帖  帮顶

手机版|VR开发网 统计 津ICP备18009691号
网安备12019202000257

GMT+8, 2021-9-23 10:23 AM

返回顶部