admin 管理员组

文章数量: 887021


2024年4月13日发(作者:vb中mid函数的使用方法示例)

维普资讯

工程技术 武汉船舶职业技术学院学报2007年第2期 

基于OPENGL技术与3DS MAX 

的3D虚拟校园情景开发 

李莹,陈启祥 

(湖北工业大学计算机学院,湖北武汉430068) 

摘 要研究在普通的PC机下开发高质量的视景仿真系统。在Window XP系统下,以Visual C++为开发平台,利用 

OpenGL和3DS MAX,运用面向对象编程的思想,采用Win32Application的编程方法。首先介绍了OpenGL及如何利 

用它生成地面和天空。采用OpenGL函数进行摄像漫游和调入由3DS MAX绘制的3DS模型,较好地解决了用OpenGL 

绘制复杂图形的困难性。 

关键词 开放式图形库;虚拟;建模;漫游;可视化 

中图分类号TP391.9 文献标志码 A文章编号 1671—8100(2OO7)02~0037—04 

随着教育事业的发展,学校教育环境和教学 

1.1地面的构成算法 

质量都在不断提升,然而,学校往往对学生的服务 

在OpenGL中,数字地面是三维的,在本文 

性工作忽视了。许多外地的潜在学生只能从文字 

中,出于校园地面原因,将地面的Y值取为0,并 

材料中了解学校情况,无法亲自来到学校对校园 

为地面进行贴图。运用三个数组将地面初始化。 

做一个直观的参观了解。利用OPENGL技术对 

(1)地域数组g-terrain[MAP—W*MAP—w] 

校园进行建模,可以让学生或家长在虚拟环境下 

[3]:这是一个构成三维地面的数组。X、Z两个 

漫游学校,对校园有较直观的了解。 

分量构成了一个平面,Y分量控制地面高度。(2) 

开放式图形库(Open Graphic Library简称 

顶点数组g—index[MAP—W*MAP—W*2]:在 

OpenGL)是美国SGI公司推出的开放式三维图 

3D图形学中引入了地面顶点的概念,并用一个一 

形软件接口工业标准,它通过集成强大的可视化 

维顶点数组(按顺序的)来记录地面顶点。这样做 

函数和其他大量的渲染、纹理影像、特殊效果,使 

的作用是可以加快三维曲面显示。(3)索引数组 

其能绘制三维物体,生成三维场景,加速了图形应 

g_texcoord[MAP—W*MAP—w][2]:是一组二 

用程序的开发。本文以Visual C++为平台,利 

维数组,它的作用是指示地面的平面坐标。 

用OpenGL建立三维场景,调用3DSMAX建模 

g_terrain[Vertex][O]一float(x)*MAP— 

的建筑模型,实现虚拟漫游。 

SCALE;//地域数组x分量 

1 OpenGL编程 

g_terrain[Vertex][1]一0;//Y分量 

g_terrain[Vertex][2]一一float(z)*MAP 

每一种程序都有它的运行环境。0penGL的 

SCALE;//z分量 

所有绘图命令(函数)都必须在0・penGL的运行 

g-texcoord[Vertex][O]:(float)x;//索引 

环境中使用,这个运行环境称为0penGL的框 数组x 

架。由于本文的程序是在Windows系统上实现 

g_texcoord[Vertex][1]:(float)z;//索引 

和运行的。所以OpenGL程序必须建立在win— 数组Z 

dows的程序框架上。 

g_index[index++]一Vertex;//顶点数组 

g_index[index++]一Vertex+MAP—W; 

收稿日期:2007—02—21 

基金项目i湖北省教育厅重大课题,编号2004Z001 

作者简介:李莹,女,硕士研究生,研究方向:虚拟仿真。 

37 

维普资讯

武汉船舶职业技术学院学报

然后显示地面,并用OpenGL贴图函数g卜 

BindTexture()将地面贴图。 

glBindTexture(GL_TEXTURE一2D,g—cac— 

2007年第2期 

TEXTUREWRAPT,GL

CLAMP);glBegin 

——

(GL—QUADS); 

glTexCoord2f(1.Of,0。Of);glVertex3f(x, 

tusEO]); 

glTexEnvf(GL

TEXTURE

ENV,GL

— 

TEXTURE-]ENV—M0DE,GL—REPLACE); 

for(int z一0;z<MAP—W一1;z++) 

glDrawElements(GL

TRIANGLE

STRIP, 

MAP

W*2,GL—UNSIGNED__INT, 

8Lg

indexl-z*MAP—W*2]); 

1.2天空的显示 

天空的做法有很多,比如纹理映射。而在本 

文中则是运用的天空盒的方法。所谓天空盒,就 

是用一矩形方盒作为天空远景贴图的载体。 

构成天空盒的载体是一长方体。在该长方体 

的前后左右上5个面贴有天空远景的5幅图形。 

但这5幅图形必须满足以下条件:(1)图形为 

BMP位图格式,尺寸(象素点)为2的N次方 

(32,64,128,256…)。(2)顶图的4边与前后左 

右图的上边相连。(3)前后左右的4幅图形必须 

首尾相连。 

glBindTexture(GL

TEXTURE

2D,tex- 

ture1);//前图形 

glTexParameteri(GL

TEXTURE

2D,GL

— 

TEXTURE_WRAP—S,GL—CLAMP); 

glTexParameteri(GL_TEXTURE

2D,GL

— 

TEXTUREWRAPT,GL

——

CLAMP);glBegin 

(GL—QUADS); 

glTexCoord2f(1.Of,0.Of);glVertex3f(X+ 

width,y,z); 

glTexCoord2f(1.0f,1.Of);glVertex3f(X+ 

width,y—卜height,z); 

glTexCoord2f(0.0f,1.Of);glVertex3f(X,Y 

+height,z); 

glTexCoord2f(0.Of,0.Of);glVertex3f(x, 

Y,z); 

glEnd(); 

glBindTexture(GL

TEXTURE

2D,tex— 

ture2);//左图形 

glTexParameteri(GL

TEXTURE

2D,GL

— 

TEXTURE—WRAP—S,GL—CLAMP); 

glTexParameteri(GL

TEXTURE

2D,GL

~ 

38 

Y,z—卜length); 

glTexCoord2f(1.Of,1.Of);glVertex3f(X,Y 

+height,z+length); 

glTexCoord2f(0.Of,1.Of);glVertex3f(X+ 

width,y—卜height,z—卜length); 

glTexCoord2f(0.Of,0.Of);glVertex3f(X+ 

width,Y,z+length); 

glEnd(); 

1.3摄像漫游 

人对世界的综合视觉观察效果,是来源于我 

们的眼睛。眼睛就像一架照相机,将外部影像反 

映到我们的大脑。在计算机3D图形处理技术中 

也有类似我们眼睛的东西gluLookAt(…)观察 

函数,如果这个观察点在OpenGL场景中的位置 

发生变化,我们在计算机屏幕上的图像(相当我们 

大脑的映像)就发生变化。 

在本文中用来改变观察点的是OpenGL的 

gluLookAt(…)函数,用PageUp和PageDown 

键来控制上下,用上下键来控制前后,用左右键来 

控制左右。但是只是右键会使视点变化,而其他 

的键只会引起目标点的变化,但视点不会变化。 

此外,我们还必须对漫游的范围有一个边界的设 

定,否则就像走进了无底深渊。 

if(KEY—D0WN(VK

LEFT))g

Angle~ 

一speed*2;//左转,方位角一 

if(KEY

DOWN(VK—RIGHT))g_Angle+ 

一speed*2;//右转,方位角+ 

rad

XZ—float(3.13149 g

Angle/180. 

Of);//计算左右旋转角度 

if(KEY

DOWN(33))g—elev+一speed;// 

PageUp键 

jf(KEY

_

DOWN(34))g_elev一=speed;// 

PageDown键 

if(g

_

elev ̄一360)g

elev一一360;//边界 

处理 

if(g

_

eleC>360)g_elev一360: 

if(KEY

DOWN(VK—UP))//前进 

{g—eye[2]+一(float)sin(rad—XZ)* 

speed;//视点Z分量 

维普资讯

——

基于OPENGL技术与3DS MAX的3D虚拟校园情景开发 李 莹,等 

MessageBox(NULL,strMessage,”Error”, 

g_eye[0]+一(float)cos(rad—xz)*speed;// 

视点X分量 

} 

if(KEY

DOWN(VK—DOWN))//后退 

{g eye[2]~一(float)sin(rad—xz)*speed; 

g_eye[0]一一(float)cos(racLxz)*speed; 

} 

if(g

eye[O] ̄MAP—SCALE)g—eye[0 ̄一 

MAP

SCALE;//视点X分量的限制 

if(g

eye[0]>(MAP—W一2)*MAP— 

SCALE)g-eye[o3:(MAP—W一2)*MAP— 

SCALE。 

if(g

eye[2]<一(MAP—W一2)*MAP— 

SCALE) 

g—eye[2]=一(MAP—W一2)*MAP— 

SCALE;//视点Z分量的限制 

if(g

_

eye[2]>一MAP—SCALE)g_eye[2]一 

MAP SCALE; 

1.4调入3DS模型的算法 

虽然OpenGL自身可以绘制三维物体,但用 

专用的3D模型工具可以帮我们实现各种复杂的 

三维物体。而在建好的OpenGL场景中调用这 

些复杂模型就可以了。要在OpenGL场景中显示 

3DS模型,首先要调入模型。 

FilePointer—fopen(strFileName,” 

rb”);//打开一个3ds文件 

//确保所获得的文件指针合法 

if(!m—FilePointer) 

f sprintf(strMessage,”Unable tO find the 

file: S!..,strFileName); 

MessageBox(NULL,strMessage,”Error”, 

MB

OK); 

return false; 

} 

当文件打开之后,首先应该将文件最开始的 

数据块读出以判断是否是一个3ds文件 

ReadChunk(m

_

CurrentChunk); 

并确保是3ds文件 

if(m

CurrentChunk一>ID!一PRIMA— 

RY) 

{sprintf(strMessage,”Unable to load PRI— 

MARY chuck from file: S!..,strFileName); 

MBLOK); 

return false; 

, 

然后开始读人数据。读人数据是用一个递归 

函数ReadNextChunk()来实现的。在读人模型 

时也要读人模型材质,用tMatlnfo newTexture 

材质链表来保存材质。 

while(pPreChunk~>bytesRead<pPre— 

Chunk一>length) 

{ReadChunk(m—CurrentChunk);//读人下 

个块 

switch(m

CurrentChunk一>ID)//判断 

块的ID号 

f…… 

case OBJECTINFO: 

ReadChunk(m

TempChunk);//读人下一 

个块 

hunk一>bytesRead+一fread(8Lversion, 

1,m

TempChunk-->length—m

TempChunk 

>bytesRead,m—FilePointer);//获得网格的 

版本号 

CurrentChunk一>bytesRead +一 m

— 

TempChunk-->bytesRead;//增加读入的字节 

数 

ReadNextChunk(pModel, m

Cur— 

rentChunk);//进入下一个块 

break; 

case MATERIAL://材质信息 

pModel-->numOfMaterials++;//材质的 

数目递增 

pModel一>pMaterials.push

back(new— 

Texture);//在纹理链表中添加一个空白纹理结 

构 

ReadNextMatChunk(pModel,m

Cur— 

rentChunk);//进入材质装入函数 

break; 

} 

显示3DS模型运用了遍历算法,结构如下: 

对模型中的每一个模块: 

{ 

39 

维普资讯

武汉船舶职业技术学院学报

如果有纹理使能纹理映射; 

对模块的每一个面: 

{ 

2007年第2期 

对面的每个顶点 

{ 

求出法向; 

如果有纹理glTexCoord2f纹理; 

} 

} 

} 

图1 3DSMAX建模 

此外,要注意OpenGL的坐标系和3DS Max 

的坐标系是不同的,3D Studio Max中的模型的Z 

轴是指向上的,而OpenGL中模型的Z轴是垂直 

屏幕指向用户的,因此需要将顶点的坐标的y和 

Z翻转过来。 

函数、可移植性强的特点。虽然用OpenGL设计 

复杂的模型很繁琐,但OpenGL良好的兼容性可 

用专用绘图工具3DS MAX绘制的图形进行调 

用,使用OpenGL制作出的三维场景更逼真。本 

文充分利用OpenGL提供的绘图、贴图和可视化 

等函数,实现了较好的虚拟场景漫游。 

参 考文 献 

2 3DSMAX建模 

任何复杂的几何结构都是由简单的基本图形 

组合构成的。在3DS MAX中已经提供了许多基 

本的二维三维图形以及相关的命令函数。对这些 

1 肖永亮.Visual c++游戏编程基础EM].电子工业出版社, 

2005,5. 

2 Richard S.Wright Jr.Michael Sweet.OpenGL超级宝典(第 

二维和三维图形运用不同的命令组合出来最终的 

实体建模见图1。 

二版)[M].人民邮电出版社,2001,6. 

3 Shamms Mortier.3D图形图像设计教程[M].电子工业出版 

社,2002,7. 

4 费广正.Visual c++6.0高级编程技术OpenGL篇[M].中 

3 结束语 

OpenGL是低层的API,它具有丰富的绘图 

国铁道出版社,2000,9. 

5唐明理.传奇的故事——学VC编游戏[M].四川电子音像 

出版中心,2004,10. 

Application of 3D Visual Reality of Campus 

with OpenGL Technology And 3DS MAX 

LI Ying,CHEN Qi—xiang 

(School of Computer,Hubei University of Technology,Wuhan 430068,China) 

Abstract:The Paper was about the development of a 3D visual reality software with personal 

computer.OpenGL,3DS MAX,the thinking of Objected--Oriented and Win32 Application 

method were utilized in the environment of Visual C++6.0.At first the paper introduced 

OpenGL and its application for drawing grounds and the sky.Furthermore,using OpenGL 

function realized the photograph roaming.At last,the paper solved the difficulty of drawing 

complicated models in OpenGL by calling in 3D models generated by 3DS MAX. 

Key words:OpenGL;visual reality;modeling;roaming;visibility 

(责任编辑:谭银元) 

40 


本文标签: 地面 纹理 天空