OpenGL中3DMAX模型的应用
摘 要:阐述如何在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的应用程序中,将可应用于飞行模拟、运动虚拟仿真、商业广告、游戏制作、影视采辑等多个领域。
#c/c++