实验十三3DS模型的显示一、实验目的1.实现3DS模型在程序中的显示与漫游2.实现MDL模型在程序中的显示与漫游3.了解3DS模型尺寸与OpenGL绘图坐标之间的关系二、实验环境硬件要求:PC机,主流配置,最好为独立显卡,显存512M以上。软件环境:操作系统:WindowsXP。语言开发工具:MicrosoftVisualstudio2005/2008,VisualC++。三、实验内容与要求:要求:实验所有步骤所生成的效果截图拷贝到实验报告文档里备查,并附上相应的代码。WORD文档命名方式:学号姓名-实验序号-实验名称。内容:1.铲车模型显示程序图1·铲车模型程序效果仔细研读程序,修改程序,将模型放入上次实验的场景中在场景中尝试添加其他模型,并查看效果1.如果屏蔽深度检测代码,模型显示会怎样变化?2.模型的纹理对场景的效果会有影响吗?提供的模型(参见实验文件夹3DSModel):1.汽车(分普通轿车和宝马车)2.飞机3.铲车(如发现贴图有问题,请立即告诉老师,同学们也可自行到网上搜寻模型)五、设置参考1)3DS模型导入设置1.工程文件准备1)添加头文件#include3ds.h#includetexture.h2)添加源程序3ds.cpp,texture.cpp2.主程序修改步骤1.变量定义C3DSModeldraw3ds[5];//有多少个模型,数组就定义多大2.//调入模型文件一般设置init()中,例如draw3ds[0].Load(“car.3ds”);draw3ds[1].Load(“house.3ds”);//模型调入后,位置处在世界坐标系的原点3.//显示写在显示回调函数Display()中glEnable(GL_LIGHTING);//启用光源glEnable(GL_TEXTURE_2D);//启用纹理//通过图形变换使得模型原来的尺寸和世界坐标系得尺寸保持一致图形变换glScalef(x,y,z);draw3ds[0].Render();//显示模型1draw3ds[1].Render();//显示模型2glDisable(GL_LIGHTING);//使用后关闭光源glDisable(GL_TEXTURE_2D);//使用后关闭纹理4.//释放资源,释放内存draw3ds[0].Release();draw3ds[1].Release();6.注意:要启用深度检测六、思考题哪几个因素影响3DS模型的显示效果?如果想调用不同大小的模型都能在同一个程序正确地显示,程序应该怎样修改?七、加分题在网上查找模型或者自己设计模型,调入自己设计的带光照的3D新场景(须有OpenGL绘制的其他物体)中。八、演示程序1)3DSModel_chanche.exe//3DS模型铲车效果演示九、附属程序1.铲车模型显示主程序3DSModel(带mp3音乐播放功能)#includestdafx.h#includewindows.h#includemath.h#include3ds.h#includeTexture.h#includeglut.h#includefmod.h////音频库的头文件#pragmacomment(lib,fmodvc.lib)//音频库的静态链接库FSOUND_STREAM*mp3back;voidinit(void);voidDisplay(void);voidKeyboard(intkey,intx,inty);voiddraw3DSModel();voidReshape(GLsizeiw,GLsizeih);voidmyidle();C3DSModeldraw3ds[5];//有多少个模型,数组就定义多大floateyex=0,eyey=0,eyez=100,atx=0,aty=0,atz=0;floatrotatex,rotatey;intAPIENTRY_tWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPTSTRlpCmdLine,intnCmdShow){UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);char*argv[]={hello,};intargc=2;//must/shouldmatchthenumberofstringsinargvglutInit(&argc,argv);//初始化GLUT库;glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);//设置显示模式;(缓冲,颜色类型)glutInitWindowSize(500,500);glutInitWindowPosition(1024/2-250,768/2-250);glutCreateWindow(3D-cubetexture);//创建窗口,标题为“Rotating3DWorld”;glutReshapeFunc(Reshape);init();glutDisplayFunc(Display);//用于绘制当前窗口;glutIdleFunc(myidle);glutMainLoop();//表示开始运行程序,用于程序的结尾;return0;}voidinit(){//调入模型文件一般设置init()中,例如draw3ds[0].Load(chanche.3ds);glClearColor(1,1,1,1);glEnable(GL_DEPTH_TEST);//启用深度测试if(FSOUND_Init(44100,32,0))//把声音初始化为khz{//载入文件bgmusic.mp3mp3back=FSOUND_Stream_OpenFile(1.mp3,FSOUND_LOOP_NORMAL,0);}FSOUND_Stream_Play(FSOUND_FREE,mp3back);}voidDisplay(void){glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(eyex,eyey,eyez,atx,aty,atz,0,1,0);glRotatef(rotatex,1,0,0);glRotatef(rotatey,0,1,0);glScalef(0.5,0.5,0.5);draw3DSModel();//绘制玩物glutSwapBuffers();}voiddraw3DSModel(){glEnable(GL_TEXTURE_2D);glPushMatrix();draw3ds[0].Render();glPopMatrix();glDisable(GL_TEXTURE_2D);}voidspecialkeyboard(intkey,intx,inty){if(key==GLUT_KEY_UP){eyey+=5;aty+=5;}if(key==GLUT_KEY_DOWN){eyey-=5;aty-=5;}glutPostRedisplay();}voidKeyboard(unsignedcharkey,intx,inty){switch(key){case'w':eyez-=5;atz-=5;break;case's':eyez+=5;atz+=5;break;case'a'://eyex-=5;eyex-=5;atx-=5;break;case'd'://eyex+=5;eyex+=5;atx+=5;break;}glutPostRedisplay();}voidReshape(GLsizeiw,GLsizeih){glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(90,w/h,2,2500);glViewport(0,0,w,h);glMatrixMode(GL_MODELVIEW);glLoadIdentity();}voidmyidle(){Sleep(100);rotatex+=0.1;rotatey+=0.1;glutPostRedisplay();}2.读取3DS模型程序3ds.cpp#includestdafx.h#include3ds.h#includeTexture.h#includeglaux.h//构造函数C3DSModel::C3DSModel(){//初始化文件指针m_FilePtr=NULL;//定义一个默认的材质(灰色)tMaterialdefaultMat;defaultMat.isTexMat=false;strcpy(defaultMat.matName.string,5DG_Default);defaultMat.color[0]=192;defaultMat.color[1]=192;defaultMat.color[2]=192;m_3DModel.pMaterials.push_back(defaultMat);//初始化保存DS模型的结构体m_3DModel.numOfMaterials=1;m_3DModel.numOfObjects=0;}//析构函数C3DSModel::~C3DSModel(){m_3DModel.pMaterials.clear();m_3DModel.pObject.clear();}//载入ds文件BOOLC3DSModel::Load(char*strFileName){charstrMessage[128]={0};tChunkchunk={0};//打开文件m_FilePtr=fopen(strFileName,rb);//如果文件打开失败if(!m_FilePtr){sprintf(strMessage,3DS文件%s不存在!,strFileName);MessageBoxA(NULL,strMessage,Error,MB_OK);returnfalse;}//读取ds文件的第一个ChunkReadChunk(&chunk);//检查是否是ds文件if(chunk.ID!=PRIMARY){sprintf(strMessage,读取文件%s失败!,strFileName);MessageBoxA(NULL,strMessage,Error,MB_OK);fclose(m_FilePtr);returnfalse;}//开始读取ds文件ReadPrimary(chunk.length-6);//计算每个顶点的法线量ComputeNormals();//关闭打开的文件fclose(m_FilePtr);m_FilePtr=NULL;//对有纹理的材质载入该纹理for(inti=0;im_3DModel.numOfMaterials;i++){if(m_3DModel.pMaterials[i].isTexMat){if(!BuildTexture(m_3DModel.pMaterials[i].mapName.string,m_3DModel.pMaterials[i].texureId)){//纹理载入失败sprintf(strMessage,3DS纹理文件载入失败:%s!,m_3DModel.pMaterials[i].mapName.string);MessageBoxA(NULL,strMessage,Error,MB_OK);}}}returntrue;}//从文件中读取个字节BYTEC3DSModel::ReadByte(void){BYTEresult=0;fread(&result,1,1,m_FilePtr);returnresult;}//从文件中读取个字节WORDC3DSModel::ReadWord(void){returnReadByte()+(ReadByte()8);}/