高海芳,王天雷,邱杰,康献民,4,王大承,4
基于OpenGL的3DS模型的导入与控制
高海芳1,王天雷2,邱杰3,康献民1,4,王大承1,4
(1. 五邑大学 机电工程学院,广东 江门 529020;2. 五邑大学 信息工程学院,广东 江门 529020;3. 国家摩托车及配件质量监督检验中心,广东 江门 529000;4. 五邑大学 摩托车研究院,广东 江门 529020)
研究了在VC++6.0环境下利用OpenGL导入3DS模型的两种方法,并给出了具体实现过程和技术要点,两种导入方法比较结果说明:读入3DS文件类的方法优于文件转换法,导入的模型图的失真度很小,并可方便实现平移、旋转、缩放、拾取等人机交互控制.
OpenGL;3DS模型;人机交互
OpenGL是SGI公司开发的一套高性能的图形处理系统,是图形硬件的软件界面[1]. 通过OpenGL,程序员可以创建人机交互的应用程序,实现具有逼真效果的三维图形图像,但是利用OpenGL绘制复杂的三维模型的工作量和难度较大;而利用3DS MAX可灵活绘制复杂的三维模型及动画,但不能实现人机交互;因此,越来越多的图形、图像制作者选择利用OpenGL与3DS MAX的优势,即使用3DS MAX对复杂模型建模,再将它导入OpenGL中编程,实现交互式的动画.
3DS模型文件由许多Chunk组成,每个Chunk包括一个头和一个主体,Chunk是相互嵌套的,这就决定了必须以递归的方式读取它们. Chunk的头又由2部分组成:ID是一个整型数,表示Chunk的含义;Chunk的长度是一个长整型数(以字节为单位,包括头),包含了下一个Chunk的相对位置信息[2-3]. 3DS模型文件中有一个基本Chunk,其ID是4D4D,基本Chunk又称为主Chunk,主Chunk包括3D编辑器Chunk和关键帧Chunk. 3DS模型文件中3个主要的Chunk ID信息见表1.
表1 3DS模型文件中的3个主要的Chunk ID信息
文件转换是指直接采用VIEW3DS等软件将3DS文件转换为OpenGL所需要的C文件. 具体实现过程如下:1)将VIEW3DS软件在开始菜单的运行程序中运行;2)将需要转换的3DS文件拖入即可得到一个后缀名为.h和.gl的文件;3)将这2个文件拷贝到已编好的OpenGL框架程序中,并在工程菜单中加入这2个文件;4)在视类的执行文件中添加该头文件,如#include "BASE.h",并添加成员变量int Model,在初始化函数中添加代码:Model =GL3DS_initialize_BASE(),在绘制场景函数中添加代码:glCallList(Model1),编译运行程序即可得到图1所示的模型图.该方法使用简单,但模型在导入过程中丢失了部分材质及纹理,有明显的失真;由于模型以一个数据文件存放,也不便于控制.
图1 文件转换法导入的模型图
由于3DS模型文件中的编辑Chunk、颜色Chunk、材质Chunk、纹理Chunk最重要,对3DS模型起关键性的作用,因此建立读入3DS文件的类就是怎样读入这些关键的Chunk. 在VC++6.0的MFC框架中定义一个名为3DSload的类,用于3DS文件的读入与重绘,该类中主要定义了几个结构体及主要函数.
1)主要结构体:
a. 颜色结构体
typedef struct {
GLfloat red; 颜色的红色分量
GLfloat green; 颜色的绿色分量
GLfloat blue; 颜色的蓝色分量
GLfloat alpha;
}OUTGL_RGB;
b. 顶点结构
typedef struct {
GLfloat u,v; 纹理坐标
GLfloat nx,ny,nz; 法向量
GLfloat x,y,z; 坐标值
}OUTGL_VERTEX;
c. 对象结构体M3DSObject用于存取读入的内容
typedef struct{
GLuint NumVertex;
OUTGL_VERTEX *VertexLists;
GLuint NumPolygon;
GLuint strip;
POLYGONLIST *PolygonLists;
}M3DSObject;
2)主要函数:
M3DSObject* Load3DSObject(char *filename); 读取3DS文件函数
void Draw3DSObject(M3DSObject *object);3DS模型重绘函数
void Unitize3DSObject(M3DSObject *object);3DS模型归一化函数将3DS模型归一化,即将模型平移到原点,并缩放到每个坐标均在[-1,1]的立方体中.
3DSload类编写完成后即可按下面的步骤导入3DS模型:
1)在MFC的文档类中添加成员变量M3DSObject *m_Real3DS1用于存取导入的模型.
2)添加OnOpenDocument的消息响应函数. 为了能够导入多个模型并便于控制,采用显示列表的方法加载模型. 在OnOpenDocument的消息响应函数中添加源程序:
BOOL CRead3DSDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
glNewList(1,GL_COMPILE);创建显示列表
m_Real3DS1=Load3DSObject("BASE.3DS");导入第一个名为BASE.3DS的模型
Draw3DSObject(m_Real3DS1);调用3DSload类的成员函数重绘3DS模型
glEndList();
...
glNewList(7,GL_COMPILE);
m_Real3DS2=Load3DSObject("6.3DS");
Draw3DSObject(m_Real3DS2);
glEndList();
}
3)在视图类中添加成员函数DrawWithOpenGL()重绘导入模型.
4)在视图类中响应OnPaint()函数,并在该函数下调用DrawWithOpenGL()函数显示3DS模型.
编译运行程序即可得到如图2所示的 6轴机器人模型. 由图2可知:由于采用创建显示列表的方法分别导入机器人的各个关节,容易对每个关节实施控制,所以导入的机器人模型不存在失真. 但是该方法操作比较复杂,要求编程者对3DS模型结构有较好的了解,并且有一定的VC++基础.
图2 3DS文件类读入方法导入的 6轴机器人模型图
由3DS文件类的读入方法导入的3DS模型能很容易地实现平移、旋转、缩放和拾取等人机交互控制.
模型图平移采用函数glTranslatef(m_xTranslation, m_yTranslation, m_zTranslation)实现,其中3个参数对应3个坐标轴. 模型图旋转采用函数glRotatef(m_Rotation,x,y,z),其中m_Rotation表示旋转角度,、、的取值为0或1[4],取1表示该轴即为旋转轴. 例如:glRotatef(30.0f,1.0f,0.0f,0.0f)表示绕轴旋转30º. 通过平移与旋转可对图2中机器人模型的各个关节进行控制,实现如图3所示的效果. 为实现实时控制,采用鼠标右键与Ctrl键组合实现旋转控制,鼠标右键与Shif键组合实现平移控制. 其实现过程如下:
图3 平移与旋转后的3DS模型图
1)定义一个Bool型变量m_RButtonDown,判断鼠标右键是否按下:变量为真表示按下,为假表示松开.
2)定义一个Cpoint变量存取鼠标右键按下的位置,该点的位置与鼠标平移后松开的位置即可表示为旋转与平移控制函数的参数(由于通过响应鼠标按下的消息所获得的点是,平面内的二维点,而平移函数中轴方向的参数是没有办法获得的,所以通过鼠标右键移动只能使导入的3DS模型在,平面内移动).
3)通过if语句:if(m_ReftButtonDown&&(nFlags&MK_SHIFT/MK_CTRL))判断是旋转控制还是平移控制.
模型图缩放采用函数glScalef(m_xScaling,m_yScaling,m_zScaling)实现,其中3个参数对应于3个坐标轴的缩放比例. 采用一个Slider控件控制缩放,缩放函数的参数可通过Slider控件的移动获得,一般将函数glScalef(m_xScaling,m_yScaling,m_zScaling)中的3个参数设为大小一样.
在OpenGL程序中拾取是在投影变换(Projection Transformation)阶段利用投影变换中归一化视体操作来实现的. 拾取时,我们用一个选择框来选择物体;设置模型图拾取控制函数gluPickMatrix (,,width,height,viewport[4]),其中,是鼠标点击到窗口上的坐标,width和height就是以(,)为中心的拾取框的宽度和高度,viewport是当前窗口的大小;初始化名称堆栈函数glSelectBuffer (SIZE,selectBuf),SIZE表示堆栈大小,selectBuf表示堆栈名称,初始化对象名称函数glInitNames(),加载对象名称glLoadName(GLuint name),name为整型数,表示加载对象名称. 具体实现模型图拾取控制的流程如图4所示.
图4 实现模型图拾取控制的流程
将3DS模型导入OpenGl软件中,降低了OpenGl复杂建模的难度,可以得到较真实的三维复杂物体模型. 采用在OpenGL程序中引入3DS数据模型文件的方法得到了较好的三维效果,同时可以进行人机交互处理,成果可用于机器人仿真软件开发、3D游戏开发等领域.
[1] 李新,李姗姗. 3DS模型在OpenGL中的读取和重绘[J]. 首都师范大学学报:自然科学版,2008, 29(2): 101-104.
[2]OpenGL体系结构审核委员会. OpenGL编程指南[M]. 4版. 邓郑祥. 北京:人民邮电出版社,2005.
[3]WRIGHT R S, APCHAK J B. OpenGL超级宝典[M]. 徐波. 北京:人民邮电出版社,2005.
[4] 张正波,牟彦,黄华,等. OpenGL实现3DS文件中的模型自由旋转[J]. 计算机工程与应用,2005, 41(13): 98-100.
[责任编辑:孙建平]
Import and Control of 3DS Models Based on OpenGL
GAOHai-fang1,WANGTian-lei2,QIUJie3,KANGXian-min1,4,WANGDa-cheng1,4
Two methods for importing the 3DS model using OpenGL in the VC + +6.0 environment are studied and the specific implementation procedures and technical points are given. A comparison of the two methods shows that the 3DS file-class method is better than the file conversion method as it causes less model diagram distortion and can easily achieve such human-computer interaction as translation, rotation, scaling and picking up.
OpenGL; 3DS model; human-computer interaction
1006-7302(2010)03-0005-32
TP311
A
2010-03-15
广东省教育部产学研合作专项项目(2008B090500081)
高海芳(1984—),男,湖南常德人,硕士研究生,研究方向:自动化控制,E-mail: gaohaitian125@163.com;王大承,教授,硕士生导师,通信作者,研究方向:智能控制与测试、特种加工、摩托车设计,E-mail:dcwang@wyu.edu.cn.