您好,欢迎访问三七文档
当前位置:首页 > 建筑/环境 > 工程监理 > 实验三3DMAX模型设计与VC调用
实验三3DMAX模型设计与VC调用一、实验目的与要求1.学习3DMAX的数学原理、图形结构、文件格式;2.掌握3DMAX系统模块、功能结构、图形绘制技术;3.掌握3DMAX光照、材质、纹理、动画制作的基本原理;4.掌握基于VisualC++环境调用3DS等格式文件的原理、过程与步骤;5.掌握基于OpenGL环境控制3DMAX模型的原理、过程与步骤;6.熟悉VisualC++、OpenGL与3DMAX的混合编程与接口技术。二、实验仪器与设备1.微型电子计算机80台2.Windows2000以上版本操作系统80套3.VisualC++6.0开发系统80套4.3DMAX7.0以上开发系统80套5.OpenGL2.0以上函数库80套三、实验内容与步骤1.用VisualC++6.0、OpenGL为工具,基于Win32编写一段程序读取3DS文件1.1实验流程图图3-1基于Win32流程图1.2主要代码//构造函数的功能是初始化tChunk数据CLoad3DS::CLoad3DS(){读入对象的各种信息(如:顶点、面、材质名称、纹理坐标、RGB颜色、顶点索引)显示输出结果结束判断是否是3ds文件打开此3ds文件提示出错是否开始读入数据m_CurrentChunk=newtChunk;//初始化并为当前的块分配空间m_TempChunk=newtChunk;//初始化一个临时块并分配空间}//打开一个3ds文件,读出其中的内容,并释放内存boolCLoad3DS::Import3DS(t3DModel*pModel,char*strFileName){charstrMessage[255]={0};//打开一个3ds文件m_FilePointer=fopen(strFileName,rb);//确保所获得的文件指针合法if(!m_FilePointer){sprintf(strMessage,Unabletofindthefile:%s!,strFileName);MessageBox(NULL,strMessage,Error,MB_OK);returnfalse;}//当文件打开之后,首先应该将文件最开始的数据块读出以判断是否是一个3ds文件//如果是3ds文件的话,第一个块ID应该是PRIMARY//将文件的第一块读出并判断是否是3ds文件ReadChunk(m_CurrentChunk);//确保是3ds文件if(m_CurrentChunk-ID!=PRIMARY){sprintf(strMessage,UnabletoloadPRIMARYchuckfromfile:%s!,strFileName);MessageBox(NULL,strMessage,Error,MB_OK);returnfalse;}//现在开始读入数据,ProcessNextChunk()是一个递归函数//通过调用下面的递归函数,将对象读出ProcessNextChunk(pModel,m_CurrentChunk);//在读完整个3ds文件之后,计算顶点的法线ComputeNormals(pModel);//释放内存空间CleanUp();returntrue;}//下面的函数释放所有的内存空间,并关闭文件voidCLoad3DS::CleanUp(){fclose(m_FilePointer);//关闭当前的文件指针deletem_CurrentChunk;//释放当前块deletem_TempChunk;//释放临时块}//下面的函数读出3ds文件的主要部分voidCLoad3DS::ProcessNextChunk(t3DModel*pModel,tChunk*pPreviousChunk){t3DObjectnewObject={0};//用来添加到对象链表tMaterialInfonewTexture={0};//用来添加到材质链表unsignedintversion=0;//保存文件版本intbuffer[50000]={0};//用来跳过不需要的数据m_CurrentChunk=newtChunk;//为新的块分配空间//下面每读一个新块,都要判断一下块的ID,如果该块是需要读入的,则继续进行//如果是不需要读入的块,则略过//继续读入子块,直到达到预定的长度while(pPreviousChunk-bytesReadpPreviousChunk-length){//读入下一个块ReadChunk(m_CurrentChunk);//判断块的ID号switch(m_CurrentChunk-ID){caseVERSION://文件版本号//在该块中有一个无符号短整型数保存了文件的版本//读入文件的版本号,并将字节数添加到bytesRead变量中m_CurrentChunk-bytesRead+=fread(&version,1,m_CurrentChunk-length-m_CurrentChunk-bytesRead,m_FilePointer);//如果文件版本号大于3,给出一个警告信息if(version0x03)MessageBox(NULL,This3DSfileisoverversion3soitmayloadincorrectly,Warning,MB_OK);break;caseOBJECTINFO://网格版本信息//读入下一个块ReadChunk(m_TempChunk);//获得网格的版本号m_TempChunk-bytesRead+=fread(&version,1,m_TempChunk-length-m_TempChunk-bytesRead,m_FilePointer);//增加读入的字节数m_CurrentChunk-bytesRead+=m_TempChunk-bytesRead;//进入下一个块ProcessNextChunk(pModel,m_CurrentChunk);break;caseMATERIAL://材质信息//材质的数目递增pModel-numOfMaterials++;//在纹理链表中添加一个空白纹理结构pModel-pMaterials.push_back(newTexture);//进入材质装入函数ProcessNextMaterialChunk(pModel,m_CurrentChunk);break;caseOBJECT://对象的名称//该块是对象信息块的头部,保存了对象的名称//对象数递增pModel-numOfObjects++;//添加一个新的tObject节点到对象链表中pModel-pObject.push_back(newObject);//初始化对象和它的所有数据成员memset(&(pModel-pObject[pModel-numOfObjects-1]),0,sizeof(t3DObject));//获得并保存对象的名称,然后增加读入的字节数m_CurrentChunk-bytesRead+=GetString(pModel-pObject[pModel-numOfObjects-1].strName);//进入其余的对象信息的读入ProcessNextObjectChunk(pModel,&(pModel-pObject[pModel-numOfObjects-1]),m_CurrentChunk);break;caseEDITKEYFRAME://跳过关键帧块的读入,增加需要读入的字节数m_CurrentChunk-bytesRead+=fread(buffer,1,m_CurrentChunk-length-m_CurrentChunk-bytesRead,m_FilePointer);break;default://跳过所有忽略的块的内容的读入,增加需要读入的字节数m_CurrentChunk-bytesRead+=fread(buffer,1,m_CurrentChunk-length-m_CurrentChunk-bytesRead,m_FilePointer);break;}//增加从最后块读入的字节数pPreviousChunk-bytesRead+=m_CurrentChunk-bytesRead;}//释放当前块的内存空间deletem_CurrentChunk;m_CurrentChunk=pPreviousChunk;}//下面的函数处理所有的文件中对象的信息voidCLoad3DS::ProcessNextObjectChunk(t3DModel*pModel,t3DObject*pObject,tChunk*pPreviousChunk){intbuffer[50000]={0};//用于读入不需要的数据//对新的块分配存储空间m_CurrentChunk=newtChunk;//继续读入块的内容直至本子块结束while(pPreviousChunk-bytesReadpPreviousChunk-length){//读入下一个块ReadChunk(m_CurrentChunk);//区别读入是哪种块switch(m_CurrentChunk-ID){caseOBJECT_MESH://正读入的是一个新块//使用递归函数调用,处理该新块ProcessNextObjectChunk(pModel,pObject,m_CurrentChunk);break;caseOBJECT_VERTICES://读入是对象顶点ReadVertices(pObject,m_CurrentChunk);break;caseOBJECT_FACES://读入的是对象的面ReadVertexIndices(pObject,m_CurrentChunk);break;caseOBJECT_MATERIAL://读入的是对象的材质名称//该块保存了对象材质的名称,可能是一个颜色,也可能是一个纹理映射。同时在该块中也保存了//纹理对象所赋予的面//下面读入对象的材质名称ReadObjectMaterial(pModel,pObject,m_CurrentChunk);break;caseOBJECT_UV://读入对象的UV纹理坐标ReadUVCoordinates(pObject,m_CurrentChunk);break;default://略过不需要读入的块m_CurrentChunk-bytesRead+=fread(buffer,1,m_CurrentChunk-length-m_CurrentChunk-bytesRead,m_FilePointer);break;}//添加从最后块中读入的字节数到前面的读入的字节中pPreviousChunk-bytesRead+=m_CurrentChunk-bytesRead;}//释放当前块的内存空间,并把当前块设置为前面块deletem_CurrentChunk;m_CurrentChunk=pPreviousChunk;}//下面的函数处理所有的材质信息voidCLoad3DS::ProcessNextMaterialChunk(t3DModel*pModel,tChunk*pPreviousChunk){intbuffer[50000]={0};//用于读入不需要的数据//给当前块分配存储空间m_CurrentChunk=newtChunk;//继续读入这些块,知道该子块结束while(pPreviousChunk-bytesReadpPreviousChunk-length){//读入下一块ReadChunk(m_CurrentChunk);//判断读入的是什么块switch(m_CurrentChunk-ID){caseMATNAME://材质的名称//读入材质的名称m_CurrentChu
本文标题:实验三3DMAX模型设计与VC调用
链接地址:https://www.777doc.com/doc-5472686 .html