3DS读取.docx

上传人:b****3 文档编号:3675543 上传时间:2022-11-24 格式:DOCX 页数:10 大小:44.67KB
下载 相关 举报
3DS读取.docx_第1页
第1页 / 共10页
3DS读取.docx_第2页
第2页 / 共10页
3DS读取.docx_第3页
第3页 / 共10页
3DS读取.docx_第4页
第4页 / 共10页
3DS读取.docx_第5页
第5页 / 共10页
点击查看更多>>
下载资源
资源描述

3DS读取.docx

《3DS读取.docx》由会员分享,可在线阅读,更多相关《3DS读取.docx(10页珍藏版)》请在冰豆网上搜索。

3DS读取.docx

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的数量(总数)

vectorpMaterials;//存贮materials信息的列表

vectorpObject;//存贮object信息的列表

};

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;jnumOfFaces;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());

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1