|
作者:不详
来源:CAD世界网 时间:2005-3-13 10:40:03 |
|
|
目 录 1 前言 2 基本操作 3 模型描述及控制 4 结束语
--------------------------------------------------------------------------------
摘 要:阐述如何在OpenGL三维编程中实现3DMAX数据模型的程序控制,成果可用于飞机飞行的运动模拟和飞行实时监控等领域中。 关键词:OpenGL、3DMAX、ASE文件、投影和变换。
1、前言 OpenGL是一个硬件和图形软件接口,由于它在三维真实感图形制作中性能优秀,诸如Microsoft、SGI、IBM、DEC、SUN等计算机主导公司都采用了OpenGL标准,OpenGL已经成为事实上的高性能和交互式视景标准。Microsoft 公司在Window95/NT操作系统中支持OpenGL前,只有在昂贵的图形工作站上才能运行OpenGL程序,随着支持OpenGL图形加速卡的出现和PC机性能的提高,OpenGL在PC机上得到广泛的应用。OpenGL中很容易实现模型的各种变换、着色、光照、纹理、交互操作和动画,但是它只能提供基本几何元素的造型函数,使得复杂模型的建模相对困难。3DMAX是Kinetix公司的三维图形建模和动画软件,能方便建立各种复杂物体模型,但是很难进行程序控制。因此,我们自然想到在3DMAX中建立好复杂模型后,在OpenGL中实现对其方便控制和变换。
2、OpenGL的基本操作 1)物体的绘制:通过点、线、多边形实现。 2)变换:投影变换、几何变换、裁剪变换、视口变换。 3)着色:OpenGL提供RGBA模式和颜色索引模式,提供224种颜色。 4)纹理映射:在具体模型表面加上现实世界中物体的纹理,可使三维模型更生动。 5)交互操作和动画:OpenGL辅助函数库提供了消息响应函数,可以较方便的实现交互程序控制。 6)其它:光照、反走样、混合、雾化等功能。
3、3DMAX ASE模型描述及OpenGL控制
3.1 用C语言数据结构描述3DMAX模型 在3DMAX中建立好模型后,仅以三角形网格方式存为ASE文件(ASCII文件),在程序中我们需建立对应的模型数据结构,本文以C语言数据结构为例。 例子ASE文件包含简单的一个金字塔和球体,具体内容如下(略去头部):
*GEOMOBJECT { // 单个物体模型的开头 *NODENAME "Pyramid01" // 物体名称 ... ... *MESH { // 网格 *TIMEVALUE 0 *MESHNUMVERTEX 6 // 物体的顶点数 *MESHNUMFACES 8 // 物体的三角形面数 *MESHVERTEXLIST { *MESHVERTEX00.00000.000030.0000 // 顶点坐标 ... ... *MESHVERTEX50.00000.00000.0000 } *MESHFACELIST { // 面号和构成面的顶点 *MESHFACE0:A:0 B:1 C:2 AB:1 BC:1 CA:0 ... ... *MESHFACE7:A:4 B:5 C:1 AB:0 BC:1 CA:1 } } ... ... }
*GEOMOBJECT { // 格式同上个物体 *NODENAME "Sphere01" ... ... }
分析上面的ASE文件结构,可得到通用的对应ASE文件的C模型数据结构如下。 点的定义:
typedef struct PointType { double x,x,y; }POINTTYPE;
三角形面的定义:
typedef struct FaceType { int a,b,c; }FACETYPE;
单个物体的定义:
typedef struct ObjectType { int VertexNum; // 点的个数 POINTTYPE *PointList; // 点列表 int FaceNum; // 面的个数 FACETYPE *FaceList; // 面列表 OBJECTTYPE *Next; // 指向下一物体的指针 }OBJECTTYPE;
多个物体:
typedef struct ObjectsHead { int ObjectNum; // 物体的个数 OBJECTTYPE *ObjectList; // 物体的列表 }OBJECTSHEAD;
3.2 读入3DMAX物体数据以OpenGL实现动画 从ASE文件导入物体数据:
int GetObjects(char *FileName,OBJECTSHEAD *Objects) // 从文件中读入到Objects中 { FILE fp; // 文件指针 char line[200]; // 存储文件中一行的数据 OBJECTTYPE *p,q; POINTTYPE tempoint; FACETYPE tempface;
if (fp=open(FileName,"r")<=0) then return -1; // 读文件失败
Objects->ObjectList=NULL; Objects->ObjectNum=0;
while(not eof(fp)) { getlint(fp,line); // 从文件中读入一行到Line;自定义函数; if(JudgeIn(line,"GEOMOBJECT")) { // 物体定义的头部 q=malloc sizeof(OBJECTTYPE); // 为物体分配空间 q->Next:=NULL; if (Objects→ObjectList=NULL) p=ObjectList=q; else { p->Next:=q; p=p→Next; } ++Objects->ObjectNum; } if (JudgeIn(line,"*MESHNUMVERTEX")) { q->VertexNum=GetVertexNum(line); // 读入点数 q->PointList=(POINTTYPE *) malloc(sizeof(POINTTYPE)*q→VertexNum); } if (JudgeIn(line,"*MESHNUMFACES") ) { q->FaceNum=GetFaceNum(line); // 读入面数 q->FaceList=(FACETYPE *) malloc(sizeof(FACETYPE)*q->FaceNum); } if (JudgeIn(line," *MESHVERTEX")) { GetPoint(line,tempoint); // 读入点座标 AddPoint(q->PointList,tempoint); }
// 将点加入点列表中 if(JudgeIn(line," * MESHFACE")) { GetFace(line,temface); // 读入面 AddFace(q->PointList,temface); } // 将面加入面列表中 } // While语句结束
fclose(fp); return 1; }
在OpenGL中实现动画控制:
#include <GL/gl.h> // OpenGL核心库 #include <GL/glu.h> // OpenGL实用库 #include <GL/glaux.h> // OpenGL辅助库
OBJECTSHEAD *Objects; Gldouble rx=0,ry=0,rz=0; // rx,ry,rz为物体旋转的角度 void CALLBACK myReshape(GLSize w,Glsize h) // 窗口改变尺寸回调函数 { glViewPort(0,0,w,h); } void CALLBACK display() // 显示物体回调函数 { int j,k; OBJECTTYPE *p; Delay(1000); Rx=rx+0.1; Ry=ry+0.1; Rz=rz+0.1;
glClear(GLCOLORBUFFERBIT); // 清除OpenGL的颜色缓冲 glPushMatrix(); glRotate(rx,ry,rz,0.0); // 旋转物体
p=Objects->ObjectList;
for( j=1;j<Objects->num;j++) { for(k=1;k>p->FaceNum;k++) { glBegin(GLTRIANGLES); // 用OpenGL命令绘制三角形网格 glVertex3f(p->PointList[(p->Face-List[i]).a], p->PointList[(p->Face-List[i]).b]); glVertex3f(p->PointList[(p->Face-List[i]).b], p->PointList[(p->Face-List[i]).c]); glVertex3f(p->PointList[(p->Face-List[i]).c], p->PointList[(p->Face-List[i]).a]); glEnd(); } p=p->Next; } glPopMatrix(); glFlush()l; // 与显示区交换数据 }
void main(void) { auxInitDisplayMode(AUXSINGLE|AUXRGB); // 初始化显示模式 auxInitPosition(0,0,400,400); // 初始化窗口位置和大小 auInitWindow("OPENGL-3DMAX例子"); // 标题 glClearColor(0.0,0.0,0.0,0.0); // 清除显示区 auxReshapeFunc(myReshape); auxMainLoop(display); }
4、结束语 把3DMAX模型应用于OpenGL中,降低了OpenGL复杂建模的难度,我们可以得到较真实的复杂物体模型。在飞机运动模拟和远程姿态监控的具体应用中,我们在OpenGL程序中引入3DMAX飞机模型,得到了满意的三维动画效果。同样,我们还可以编制AutoCAD、UG等多种图形接口程序,把在AutoCAD、UG等CAD软件中建立的物体模型引入OpenGL的应用程序中,将可应用于飞行模拟、运动虚拟仿真、商业广告、游戏制作、影视采辑等多个领域。
参考文献 [1] 白燕斌/史惠康等编,《OpenGL三维图形库编程指南》,北京:机械工业出版社.1998.11。 [2] S.Ellion.P.Miller著,张若青/古梅译,《3DMAX STUDIO技术精粹》,北京:清华大学出版社.1997.9。
|
|
|
|
|
| 上一篇文章:3DS Max 7 渲染器全攻略:光线跟踪渲染(一)
|
| 下一篇文章:人机工程学和工业设计
|
|
相关文章:
|
|
|
|
|