3DS读取.docx
- 文档编号:3675543
- 上传时间:2022-11-24
- 格式:DOCX
- 页数:10
- 大小:44.67KB
3DS读取.docx
《3DS读取.docx》由会员分享,可在线阅读,更多相关《3DS读取.docx(10页珍藏版)》请在冰豆网上搜索。
3DS读取
在OpenGL中读取3DS模型文件
这里要解决的一个关键问题是:
如何在OpenGL中读取3DS模型文件。
在这部分介绍了3DS文件的存储格式,给出了OpenGL与3DS的接口编程,这对三维模型的创建提供了极大的方便,还综合运用其他的技术和算法来完成三维动画。
6.13ds文件格式简介
3DS文件由许多块组成,每个块首先描述其信息类别,即该块是如何组成的。
块的信息类别用ID来标识,块还包含了下一个块的相对位置信息。
因此,即使不理解一个块的含义,也可以很容易地跳过它,因为该块中指出了下一个块的相对于该块起始位置的偏移字节数。
与许多文件格式一样,3DS二进制文件中的数据也是按低位在前、高位在后的方式组织的,例如,2个十六进制字节,4A5C组成的整型数,表明5C是高位字节,4A是低位字节;对于长整型数,如:
4A5C3B8F表明5C4A是低位字,而8F3B是高位字。
下面描述块的具体定义。
块的前两项信息分别是:
块的ID和块的长度(下一个块相对于该块的字节偏移量),块的ID是一个整型数,而块的长度是一个长整型数。
每个块实际上是一个层次结构,不同类型的块,其层次结构也不相同。
3DS文件中有一个基本块,其ID是4D4D,每一个3DS文件的开头都是由这样一个块构成。
基本块内的块称为主块。
为了对块的层次结构有一个初步的认识,下面给出一个图表来说明不同类型(ID)的块及其各自在文件中的位置。
如下图所示给每一个块都起了一个名字,这样更便于理解或直接转换为源程序。
图6.13DS文件结构图
颜色块是文件中自始至终都能见到的一种块类型,颜色块总共有3种类型,它们是COL_RGB,COL_TRU和COL_UNK。
6.2存储3ds文件的数据结构
本节将对程序中所用到的一些重要数据结构进行简单说明,以便使读者更进一步了解3ds文件所存储的数据。
1.t3Dmodel:
structt3DModel
{
intnumOfObjects;//object的数量(总数)
intnumOfMaterials;//materials的数量(总数)
vector
vector
};
2.tMaterialInfo:
structtMaterialInfo
{
charstrName[255];//材质的名字
charstrFile[255];//材质的文件名(真正存在harddisk的bmp)
BYTEcolor[3];//object的颜色(RGB)(0~255)
InttexureId;//材质的ID
}
3.3DObject:
structt3DObject
{
intnumOfVerts;//object的顶点数
intnumOfFaces;//object的面数
intnumTexVertex;//材质坐标的个数
intmaterialID;//材质ID,正是材质数组中的索引
boolbHasTexture;//有材质就为真
charstrName[255];//object的名字
CVector3*pVerts;//object的顶点,将会指向一个数组
CVector3*pNormals;//object的法线(只是一个近似的法线)将会指向一个数组
CVector3*pFaceNorm;//面的法线,将会指向一个数组
CVector3*pFaceVert1;//面的顶点x,将会指向一个数组
CVector3*pFaceVert2;//面的顶点y,将会指向一个数组
CVector3*pFaceVert3;//面的顶点z,将会指向一个数组
CVector2*pTexVerts;//材质的坐标(二维)将会指向一个数组
tFace*pFaces;//面的结构(在后面有注解)将会指向一个数组
};
其中:
structtFace
{
intvertIndex[3];//组成面三角形顶点的索引(整型)
intcoordIndex[3];//组成面三角形材质的索引(整型)
};
6.33D动画的实现
读取3DS文件的全部操作封装在了CLoad3DS类中,有关CLoad3DS类的具体定义所附光盘中的源程序3ds.cppand3ds.h。
/////////////////////////////////IMPORT3DS\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
//
//Thisiscalledbytheclienttoopenthe.3dsfile,readit,thencleanup
//
//////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
boolCLoad3DS:
:
Import3DS(t3DModel*pModel,char*strFileName)
{
charstrMessage[255]={0};
//Openthe3DSfile
m_FilePointer=fopen(strFileName,"rb");
//Makesurewehaveavalidfilepointer(wefoundthefile)
if(!
m_FilePointer)
{
sprintf(strMessage,"Unabletofindthefile:
%s!
",strFileName);
MessageBox(NULL,strMessage,"Error",MB_OK);
returnfalse;
}
//Oncewehavethefileopen,weneedtoreadtheveryfirstdatachunk
//toseeifit'sa3DSfile.Thatwaywedon'treadaninvalidfile.
//Ifitisa3DSfile,thenthefirstchunkIDwillbeequaltoPRIMARY(somehexnum)
//Readthefirstchuckofthefiletoseeifit'sa3DSfile
ReadChunk(m_CurrentChunk);
//Makesurethisisa3DSfile
if(m_CurrentChunk->ID!
=PRIMARY)
{
sprintf(strMessage,"UnabletoloadPRIMARYchuckfromfile:
%s!
",strFileName);
MessageBox(NULL,strMessage,"Error",MB_OK);
returnfalse;
}
//Nowweactuallystartreadinginthedata.ProcessNextChunk()isrecursive
//Beginloadingobjects,bycallingthisrecursivefunction
ProcessNextChunk(pModel,m_CurrentChunk);
//Afterwehavereadthewhole3DSfile,wewanttocalculateourownvertexnormals.
ComputeNormals(pModel);
//Cleanupaftereverything
CleanUp();
returntrue;
}
See光盘中的源程序StepinGlView.cpp
//StepinGlView.cpp:
implementationoftheCStepinGlViewclass
//
……
#include"main.h"//Thisincludesourheaderfile
#include"3ds.h"//Includethe3DSheaderfile.
……
#defineFILE_NAME"moon.3ds"//Thisisthe3Dfilewewillload.
UINTg_Texture[MAX_TEXTURES]={0};//Thisholdsthetextureinfo,referencedbyanID
CLoad3DSg_Load3ds;//Thisis3DSclass.Thisshouldgoinagoodmodelclass.
t3DModelg_3DModel;//Thisholdsthe3DModelinfothatweloadin
intg_ViewMode=GL_TRIANGLES;//Wewantthedefaultdrawingmodetobenormal
boolg_bLighting=true;//Turnlightingoninitially
floatg_RotateX=0.0f;//Thisisthecurrentvalueatwhichthemodelisrotated
floatg_RotationSpeed=0.8f;//Thisisthespeedthatourmodelrotates.(-speedrotatesleft)
……
/////////////////////////////////////////////////////////////////////////////
//CStepinGlViewmessagehandlers
voidCStepinGlView:
:
Init()
{
PIXELFORMATDESCRIPTORpfd;
intn;
HGLRChrc;
m_pDC=newCClientDC(this);
ASSERT(m_pDC!
=NULL);
if(!
bSetupPixelFormat())
return;
n=:
:
GetPixelFormat(m_pDC->GetSafeHdc());
:
:
DescribePixelFormat(m_pDC->GetSafeHdc(),n,sizeof(pfd),&pfd);
hrc=wglCreateContext(m_pDC->GetSafeHdc());
wglMakeCurrent(m_pDC->GetSafeHdc(),hrc);
GetClientRect(&m_oldRect);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
//glMatrixMode(GL_MODELVIEW);
//glLoadIdentity();
g_Load3ds.Import3DS(&g_3DModel,FILE_NAME);//Loadour.3DSfileintoourmodelstructure
//Dependingonhowmanytextureswefound,loadeachone(Assuming.BMP)
//Ifyouwanttoloadotherfilesthanbitmaps,youwillneedtoadjustCreateTexture().
//Below,wegothroughallofthematerialsandcheckiftheyhaveatexturemaptoload.
//Otherwise,thematerialjustholdsthecolorinformationandwedon'tneedtoloadatexture.
//Gothroughallthematerials
for(inti=0;i { //Checktoseeifthereisafilenametoloadinthismaterial if(strlen(g_3DModel.pMaterials[i].strFile)>0) { //Usethenameofthetexturefiletoloadthebitmap,withatextureID(i). //Wepassinourglobaltexturearray,thenameofthetexture,andanIDtoreferenceit. CreateTexture(g_Texture,g_3DModel.pMaterials[i].strFile,i); } //SetthetextureIDforthismaterial g_3DModel.pMaterials[i].texureId=i; } glLightfv(GL_LIGHT0,GL_AMBIENT,m_lightAmb); glLightfv(GL_LIGHT0,GL_DIFFUSE,m_lightDif); glLightfv(GL_LIGHT0,GL_SPECULAR,m_lightSpe); glLightfv(GL_LIGHT0,GL_POSITION,m_lightPos); glEnable(GL_LIGHT0);//Turnonalightwithdefaultsset glEnable(GL_LIGHTING);//Turnonlighting glEnable(GL_COLOR_MATERIAL);//Allowcolor } voidCStepinGlView: : DrawScene() { glClearColor(0.0f,0.0f,0.0f,1.0f); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(m_posx,m_posy,-5.0f); glRotatef(m_fAngleY,0.0f,1.0f,0.0f); glRotatef(m_fAngleZ,0.0f,0.0f,1.0f); for(inti=0;i { //Makesurewehavevalidobjectsjustincase.(size()isinthevectorclass) if(g_3DModel.pObject.size()<=0)break; //Getthecurrentobjectthatwearedisplaying t3DObject*pObject=&g_3DModel.pObject[i]; //Checktoseeifthisobjecthasatexturemap,ifsobindthetexturetoit. if(pObject->bHasTexture){ //Turnontexturemappingandturnoffcolor glEnable(GL_TEXTURE_2D); //Resetthecolortonormalagain glColor3ub(255,255,255); //Bindthetexturemaptotheobjectbyit'smaterialID glBindTexture(GL_TEXTURE_2D,g_Texture[pObject->materialID]); }else{ //Turnofftexturemappingandturnoncolor glDisable(GL_TEXTURE_2D); //Resetthecolortonormalagain glColor3ub(255,255,255); } //Thisdeterminesifweareinwireframeornormalmode glBegin(g_ViewMode);//Begindrawingwithourselectedmode(trianglesorlines) //Gothroughallofthefaces(polygons)oftheobjectanddrawthem for(intj=0;j { //Gothrougheachcornerofthetriangleanddrawit. for(intwhichVertex=0;whichVertex<3;whichVertex++) { //Gettheindexforeachpointoftheface intindex=pObject->pFaces[j].vertIndex[whichVertex]; //GiveOpenGLthenormalforthisvertex. glNormal3f(pObject->pNormals[index].x,pObject->pNormals[index].y,pObject->pNormals[index].z); //Iftheobjecthasatextureassociatedwithit,giveitatexturecoordinate. if(pObject->bHasTexture){ //MakesuretherewasaUVWmapappliedtotheobjectorelseitwon'thavetexcoords. if(pObject->pTexVerts){ glTexCoord2f(pObject->pTexVerts[index].x,pObject->pTexVerts[index].y); } }else{ //Makesurethereisavalidmaterial/colorassignedtothisobject. //Youshouldalwaysatleastassignamaterialcolortoanobject, //butjustincasewewanttocheckthesizeofthemateriallist. //ifthesizeisatleastone,andthematerialID! =-1, //thenwehaveavalidmaterial. if(g_3DModel.pMaterials.size()&&pObject->materialID>=0) { //Getandsetthecolorthattheobjectis,sinceitmustnothaveatexture BYTE*pColor=g_3DModel.pMaterials[pObject->materialID].color; //Assignthecurrentcolortothismodel glColor3ub(pColor[0],pColor[1],pColor[2]); } } //Passinthecurrentvertexoftheobject(Cornerofcurrentface) glVertex3f(pObject->pVerts[index].x,pObject->pVerts[index].y,pObject->pVerts[index].z); } } glEnd();//Endthedrawing } glFinish(); SwapBuffers(wglGetCurrentDC()); }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- DS 读取