- 309.00 KB
- 2022-09-27 发布
- 1、本文档由用户上传,淘文库整理发布,可阅读全部内容。
- 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,请立即联系网站客服。
- 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细阅读内容确认后进行付费下载。
- 网站客服QQ:403074932
毕业设计(论文)基于OpenGL的下肢运动的虚拟现实仿真的设计与实现学院(系):信息工程学院专业班级:学生姓名:指导教师:\n学位论文原创性声明本人郑重声明:所呈交的论文是本人在导师的指导下独立进行研究所取得的研究成果。除了文中特别加以标注引用的内容外,本论文不包括任何其他个人或集体已经发表或撰写的成果作品。本人完全意识到本声明的法律后果由本人承担。作者签名:年月日学位论文版权使用授权书本学位论文作者完全了解学校有关保障、使用学位论文的规定,同意学校保留并向有关学位论文管理部门或机构送交论文的复印件和电子版,允许论文被查阅和借阅。本人授权省级优秀学士论文评选机构将本学位论文的全部或部分内容编入有关数据进行检索,可以采用影印、缩印或扫描等复制手段保存和汇编本学位论文。本学位论文属于1、保密囗,在年解密后适用本授权书2、不保密囗。(请在以上相应方框内打“√”)作者签名:年月日导师签名:年月日\n本科生毕业设计(论文)任务书学生姓名:专业班级:指导教师:工作单位:设计(论文)题目:基于OpenGL的下肢运动的虚拟现实仿真的设计与实现设计(论文)主要内容:本文主要研究了一个模拟下肢运动的虚拟环境的设计方法。阐述了在Vc++6.0的环境下,用OpenGL语言导入人体下肢三维图形并显示的方法,在此基础上进一步研究对下肢运动的控制,最后通过键盘输入相应的信号使其具有六自由度的运动功能,实现人体下肢运动的仿真。要求完成的主要任务:1.查阅相关文献资料15篇以上(其中英文文献不少于2篇),完成开题报告。2.研究在Vc++6.0环境下三维图形的显示和运动的控制方法,用OpenGL语言编程实现下肢模型的显示和运动的控制。3.完成不少于15000字的论文的撰写并完成答辩的相关工作。4.在设计中完成不少于3张1~2#图纸的描绘。5.完成不低于5000汉字(20000英文印刷符)的教师指定的相关文献的英译汉翻译。必读参考资料:[1]李清玲,李爽.基于OpenGL的三维人体运动仿真.计算机仿真,2011年04期.[2](美国)施瑞奈尔(DaveShreiner).OpenGL编程指南.北京:机械工业出版社,2010.[3]Cohoon,Davidson.C++ProgramDesign—AnIntroductiontoProgrammingandObject-OrientedDesign3rdEdition,2002.指导教师签名:系主任签名:院长签名(章)\n本科生毕业设计(论文)开题报告1、目的及意义(含国内外的研究现状分析)1.1研究目的及意义古往今来,疾病一直是伴随着人类的一个重大问题,也倍受全人类的关注,随着科学技术的发展,医疗器械层出不穷,很多人患者可以进行康复训练慢慢痊愈而不用再受着某些疾病的困扰,然而康复训练过程的单一和乏味让很多患者在进行训练时无法继续坚持,而且在训练过程中无法仔细观察自己的状态,缺乏安全感和信心,虚拟现实恰恰弥补了医疗器械的这个缺陷,它可以为患者的康复运动起到激励作用,同时也可提供用户一些简单的机器控制功能。三维虚拟仿真环境即虚拟现实,就是用计算机生成的一个逼真的虚拟环境,用户可以通过其自然技能通过各种传感设备同虚拟环境中的实体相互作用的一种技术。在虚拟环境中我们可以建立一个三维人体模型,即虚拟人,可以通过各种手段将人在医疗器械作用下的状态实时地反映到虚拟环境中。在虚拟环境中,患者可以更加清晰地观察到自己的运动状况,以便于进行适当的调整以更适合于康复,同时让患者沉浸于一个虚拟的世界中,可以减轻身体的痛苦和康复训练带来的乏味感,具有极大的激励作用。随着虚拟现实技术的发展,使研究者可以直接以人为研究对象,开展各种有意义的人类活动的研究。简单归纳下,它有两方面的优点,一方面,它可以模拟现实环境,模拟真人的运动,以便于研究者能够更加清晰直观地观察研究;另一方面,虚拟环境提供了一个便于测量计算的平台,能够给研究者提供准确的数据信息,给研究者的研究提供了方便。虚拟显示已经成为现阶段国内外计算机科学中的主要研究方向之一,它具有广阔的应用前景,除了用于医疗方面,还可以用于机械工程、军事、教育和空间探索等领域中,在未来的教育、生活和科研中必将发挥重要的作用,虽然本文只研究下肢运动的虚拟环境,但它是研究虚拟人的基础,是不可或缺的一部分。1.2国内外研究现状国内在虚拟环境的建模和虚拟人的运动控制方面,北京航空航天大学、中国科学院、哈尔滨工业大学以及浙江大学等学校都做了大量的理论研究及实践工作,北京航空航天大学的袁修干等人主要在人机系统仿真中的三维人体建模的方面做了研究;而在人体建模方\n面,中国科学院计算机技术研究所CAD开放实验室的詹永照等人,给出了以多面体组合建立粗略的人体,用多面体细分割来逼近真实人体曲面的方法,并在建模中考虑了人体的动态特征,为建立人体动画模型创造了条件;在虚拟人的实时运动控制方面,哈尔滨工业大学的贺怀清等人致力于研究虚拟人的实时运动控制,并实现了虚拟人的步行与跑步运动方式;中国科学院的王兆其等人在人体运动生成和控制、人体行为交互方面做了大量的研究,并且利用虚拟人合成技术实现了人体行为交互的主要工作,并将其研究成果应用于聋哑人手语交互,人体行走等方面;浙江大学的庄越挺等人在人体动画方面,提出了一种基于紧身衣和相机定标的新的人体动画技术,在基于视频的运动捕获技术方面有所研究和突破。在国外研究虚拟人运动控制的众多团体中,由蒙特利尔大学Thalmann所带领的LIG实验室是其中比较著名的一支。LIG实验室主要从事人体建模及变形的研究,人的行走、抓取等动作的研究,以及运动控制系统、运动捕获、人体动画工具的开发、人体平衡控制的研究、碰撞检测技术和基于网络的虚拟人的研究等。另一个比较著名的研究团体是宾夕法尼亚大学由Badler领导的人体建模与仿真中心。他们的研究包括参数化的关键帧技术在基于关节虚拟人的模型中的应用、逆向运动学的应用、人体的平衡研究、脊骨的建模、行走模型的建立、运动捕获的研究等。6\n2、基本内容和技术方案OpenGL是一个强大的三维图形开发接口,OpenGL中提供了大量的图形绘制、渲染、修改、显示、运动控制等函数,本次设计需要完成的任务就是在Vc++6.0的开发环境下,利用OpenGL导入人体下肢模型的3DS文件,显示下肢模型并使其在输入信号下做左转、右转、向上抬脚掌、向下压脚掌、脚掌外翻、脚掌外翻这六个动作。本文的主要内容包括:下肢模型建模,OpenGL语言中OpenGL图形库、工作结构、工作过程及动画技术等的简单介绍,基于OpenGL可视化编程,肢模型的导入方法的研究,下肢模型运动学控制策略研究,仿真环境的调试等。利用OpenGL显示下肢模型并控制其运动的方法有很多,有关键帧的方法,但是关键帧需要保存大量的顶点及面片信息,通常要进行大量的计算,比较复杂,不易懂,所以本文提供一种分块运动控制方法,通过改变输入模型各个部分的顶点坐标的方法来改变下肢模型各部分的方向,从而实现各个动作。以下是本文采用的技术方案的大致流程:①3D模型准备:利用3DSMAX这个软件构建一个人体下肢模型,由于本设计主要针对于脚踝康复,只要构建膝盖以下的下肢模型便可,要求骨骼能运动,所以必须得把下肢模型分成两段,即小腿和脚三部分,便于控制。②读入3DS文件。③保存3DS文件信息并绘制3D对象。④使用分块控制的方法控制模型运动:分块载入模型后可分别改变模型的各个部分的顶点坐标,使其能实现各种运动状态⑤定时扫描键盘输入,实时响应对应的运动⑥调试运行并加以改进。6\n3、进度安排第1-3周:查阅相关文献资料,明确研究内容,了解研究所需理论基础。确定方案,完成开题报告。第4-5周:熟悉掌握基本理论,完成英文资料的翻译,熟悉开发环境Vc++6.0。第6-9周:学习OpenGL语言。第10-12周:编程实现要求功能,并进行仿真调试。第13-15周:完成并修改毕业论文。第16周:准备论文答辩。4、指导教师意见指导教师签名:年月日\n目录摘要1Abstract21绪论31.1研究背景和意义31.2国内外研究成果31.3研究内容42系统相关理论研究42.1虚拟现实概况42.2VisualC++6.0中MFC概况62.2.1MFC基础62.2.2MFC程序结构72.2.3MFC应用程序运行机制112.3OpenGL概况112.3.1OpenGL特点和功能112.3.2OpenGL图形库122.3.33DS文件格式122.3.4基于OpenGL的图形变换技术122.3.5VC++调用OpenGL简介143系统方案规划143.1下肢模型建模方法143.2运动控制方法154系统实现174.1下肢模型建模174.2创建一MFC单文档工程174.33DS文件的读入194.43D对象的绘制204.5运动控制214.6系统设计总流程234.7仿真结果245总结与展望275.1总结275.2展望27参考文献2930\n致谢3030\n摘要为创造一个具有良好沉浸感和真实感的虚拟现实环境,给进行脚踝康复训练的患者提供动力和信心,让患者减轻康复训练时身体带来的痛苦和训练本身的无聊乏味。本文对虚拟现实的设计方法进行了深入的研究,实现了六自由度下肢的运动仿真,使得虚拟现实中的模型能够根据外界输入的信息而做相应的运动。本文主要利用3DSMAX软件实现下肢模型的建模及其修饰,在VisualC++6.0的平台下创建一个MFC单文档工程,构建了一个可视化窗口,在分析了虚拟现实和OpenGL技术的基础上,采用OpenGL技术分层次导入模型,通过OpenGL函数来逐个改变下肢模型各个模块的顶点坐标实现各种运动,即下肢左转、下肢右转、脚掌向上抬起、脚掌向下压、脚掌内翻、脚掌外翻这六个动作,并采用定时扫描的方式检测键盘输入信号,实时地完成相应的运动并提供初始状态恢复功能,最终实现了模型在虚拟现实中的显示和实时运动控制。本文采用3DSMAX和OpenGL相结合设计的三维虚拟仿真环境具有快捷、方便和通用性好等优点,采用的运动控制策略简单易懂,程序结构性强,便于二次开发。关键词:虚拟现实;OpenGL;VisualC++6.0;模型;运动控制30\nAbstractCreatingagoodsenseofimmersionandrealismoftheVirtualRealityenvironmenttoaffordpowerandconfidencetopatientswhoaredoingtherehabilitationtrainingcanreducephysicalsufferingandtheirboringofthetraining.InthispaperwestudiedthemethodofdesigningVirtualReality.Wehaverealized6DOFmotionsimulationoflowerlimbtoletthethemodelintheVirtualRealitymoveaccordingtotheexternalinputinformation.Thisarticlemainlyusesthe3DSMAXsoftwaretobuildandmodifythelowerlimbmodel,andthencreateaMFCsingledocumentengineeringinVisualC++6.0platformtoconstructavisualizationwindow.AfterstudyingtheVirtualRealityandOpenGLtechnology,weimportmodelshierarchicallybyOpenGLtechnology,andthenwechangeeachmoduleofthevertexcoordinatesofthelowerlimbmodeltorealizeallkindsofsportsthroughtheOpenGLfunction.Thesesixmovementsareleftturning,rightturning,pitchingup,pitchingdown,ectropionandvarus.Detectingofkeyboardinputsignalbythetimingscanningmodesothatthesystemcancompletesuchmovementtimely.ThispaperfinallyachievethegoalthatthemodeldisplaysintheVirtualRealityandhavethefuctionofreal-timemotioncontrol.Thispapercombinsthe3DSMAXandOpenGLtechnologysothatitmakestheprocessfast,convenientandgoodversatility.Themethodofmotioncontrolstrategyissimpleandeasytounderstand,thestructureoftheprogramisclear,itisconvenientfortwotimesdevelopmentinthefuture.KeyWords:VirtualReality;OpenGL;VisualC++6.0;model;motioncontrol30\n1绪论1.1研究背景和意义古往今来,疾病一直是伴随着人类的一个重大问题,近年来,人口老龄化,交通工具的发展及交通状况的日益拥挤造成的交通事故频发和日常的跌打损伤等原因导致越来越多的人面临着下肢运动障碍所带来的痛苦和不便,因此,健康问题备受人类关注。随着科学技术的发展,各种运动器械和医疗康复器械层出不穷,大量患者可以利用机器进行康复训练慢慢痊愈而不用再受着某些疾病的困扰,然而康复训练过程的单一和乏味让很多患者在进行训练时无法继续坚持,在训练过程中无法详细了解到自己的状态,缺乏安全感和信心,虚拟现实恰恰弥补了医疗器械的这个缺陷。虚拟现实是存在于计算机系统中的逻辑环境,通过输出设备模拟显示现实世界中的三维物体和它们的运动规律和方式,使参与者获得与现实一样的感觉的一个虚拟的境界。在虚拟现实中我们可以建立一个三维人体模型,即虚拟人,可以通过各种手段将人的运动状态实时地反映到虚拟环境中。患者通过虚拟环境可以清晰得看到自己的运动过程以便及时调整运动幅度以更合适康复,它让患者完全沉浸于一个虚拟的世界中,从而淡化了患者的身体痛苦和康复训练带来的乏味,同时也可提供用户一些简单的机器控制功能调整不同阶段训练的难易程度。总之,虚拟现实为患者的康复运动起到了激励的作用。虚拟现实技术的发展,使研究者可以直接以人为研究对象,开展各种有意义的人类活动的研究。一方面,它可以作为真人的替代者对计算机设计的车辆、工作区域、机器工具等在实际构造前进行人类工效学的评估;在真人无法到达的环境中进行各种精密的、甚至危险的试验;在军事上代替真人接受各种训练;在航空航天上代替真人接受各种训练;在医学上代替真人接受一些矫形手术等等;另一方面,它可以作为我们自身或者其它实际参与者在虚拟环境中的实时表示,在游戏、电影、广告等领域有广泛的用途【1】。虚拟现实具有多感知性、浸没感、交互性和构想性等特点,已经成为现阶段国内外计算机科学中的主要研究方向之一,虽然本文只对虚拟现实模型的控制进行了研究,但它是研究虚拟现实不可或缺的一部分,具有重大的研究意义。1.2国内外研究成果早在60年代初,随着CAD技术的发展,人们就开始研究立体声与三维立体显示相结合的计算机系统。80年代,JaronLanier提出了"虚拟现实"VR(VirtualReality)的观点,目的在于建立一种新的用户界面,使用户可以置身于计算机所表示的三维空间资料库环境中,并可以通过眼、手、耳或特殊的空间三维装置在这个环境中"环游",创造出一种"亲临其境"的感觉。国内在虚拟现实中人体的建模与运动控制方面,科研人员都做了大量的研究工作。30\n在人体建模方面,任静丽等人对虚拟现实中人体建模的几何建模方法做了详细的探讨[2];之后徐桂敏等人做了相应的研究,研究并实现了人体静态建模和人体运动行为建模,其中包括物理建模和几何建模等方法[3];在虚拟人的实时运动控制方面,哈尔滨工业大学的贺怀清,洪炳熔等人致力于研究虚拟人的实时运动控制,并实现了虚拟人的步行与跑步运动方式[4];中国科学院的王兆其等人在人体运动生成和控制、人体行为交互方面做了大量的研究,并且应用虚拟人合成技术实现了人体行为交互的主要工作,并将其研究成果应用在聋哑人手语交互,人体行走等方面[5,6];浙江大学的庄越挺、罗忠祥等人在人体动画方面,提出了一种基于紧身衣和相机定标的新的人体动画技术,在基于视频的运动捕获技术方面有所研究和突破[7]。在虚拟人的面部行为方面,中国科学院的高文等主要研究与意识行为有关的虚拟人面部图像合成技术。在国外研究虚拟显示中人体运动控制的众多团体中,由蒙特利尔大学Thalmann所带领的LIG实验室是其中比较著名的一支。LIG实验室主要从事人体建模及变形的研究[8],人的行走、抓取等动作的研究【9】,以及运动控制系统、运动捕获、人体动画工具的开发、人体平衡控制的研究、碰撞检测技术和基于网络的虚拟人的研究等。另一个比较著名的研究团体是宾夕法尼亚大学由Badler领导的人体建模与仿真中心。他们的研究包括参数化的关键帧技术在基于关节虚拟人的模型中的应用、逆向运动学的应用、人体的平衡研究、脊骨的建模、行走模型的建立、运动捕获的研究、人的冲突检测和纠正以及智能运动规划问题的研究等。加尼福尼亚大学的SanDiego和Jin-SuKim等人主要从事逆向运动学等虚拟人运动控制方面的研究【10,11】。另外,WangandChen最早提出了一种解决逆向运动学CCD(cycliccoordinatedescent)算法来解决IK问题,JeffLander等人发展了这种算法[12]。1.3研究内容本文主要利用OpenGL技术在VisualC++6.0平台下完成膝盖以下下肢模型的运动仿真的虚拟现实设计,通过输入控制信号使模型能够完成六种运动,主要研究下肢三维模型的建模方法,在VisualC++6.0平台下利用OpenGL技术导入模型的方法以及模型的运动控制策略。本文主要从3DSMAX建模,OpenGL各种相关技术,MFC工程介绍,各模块设计和实现等方面进行阐述。2系统相关理论研究2.1虚拟现实概况虚拟现实(Virtual30\nReality,简称VR,又译作灵境、幻真)是近年来出现的高新技术,也称灵境技术或人工环境。VR是一项综合集成技术,涉及计算机图形学、人机交互技术、传感技术、人工智能等领域,它用计算机生成逼真的三维视、听、嗅觉等感觉,使人作为参与者通过适当装置,自然地对虚拟世界进行体验和交互作用。使用者进行位置移动时,电脑可以立即进行复杂的运算,将精确的3D世界影像传回产生临场感。该技术集成了计算机图形(CG)技术、计算机仿真技术、人工智能、传感技术、显示技术、网络并行处理等技术的最新发展成果,是一种由计算机技术辅助生成的高技术模拟系统。虚拟现实首先是一种可视化界面技术,可以有效地建立虚拟环境,这主要集中在两个方面,一是虚拟环境能够精确表示物体的状态模型,二是环境的可视化及渲染,但它仅是计算机系统设置的一个近似客观存在的环境,是硬件、软件和外围设备的有机组合,为用户提供逼真的三维视感、听感、触感和嗅感的感受,用户可通过自身的技能以6个自由度在这个仿真环境里进行交互操作。虚拟现实的关键技术是传感技术,同时它也离不开视觉和听觉的新型可感知动态数据库技术,可感知动态数据库技术与文字识别、图像理解、语音识别和匹配技术关系密切,并需结合高速的动态数据库检索技术,不仅是利用计算机图形学或计算机成像生成的一幅画面,更重要的是人们可以通过计算机和各种人机界面与机交互,并在精神感觉上进入环境。此外虚拟现实还需结合人工智能,模糊逻辑和神经元技术。虚拟现实的基本特征有以下几点:1)多感知性(Multi-Sensory)所谓多感知是指除了一般计算机技术所具有的视觉感知之外,还有听觉感知、力觉感知、触觉感知、运动感知,甚至包括味觉感知、嗅觉感知等。理想的虚拟现实技术应该具有一切人所具有的感知功能。由于相关技术,特别是传感技术的限制,目前虚拟现实技术所具有的感知功能仅限于视觉、听觉、力觉、触觉、运动等几种。本文主要针对视觉感知和运动感知。2)浸没感(Immersion)又称临场感,指用户感到作为主角存在于模拟环境中的真实程度。理想的模拟环境应该使用户难以分辨真假,使用户全身心地投入到计算机创建的三维虚拟环境中,该环境中的一切看上去是真的,听上去是真的,动起来是真的,甚至闻起来、尝起来等一切感觉都是真的,如同在现实世界中的感觉一样。本文所设计的虚拟现实系统正是利用浸没感使康复训练患者完全沉浸在虚拟的环境当中,对患者的训练起着激励的作用。3)交互性(Interactivity)指用户对模拟环境内物体的可操作程度和从环境得到反馈的自然程度(包括实时性)。例如,康复训练的患者下肢做某种动作时,虚拟现实中的下肢模型也跟着做相应的运动。4)构想性(Imagination)强调虚拟现实技术应具有广阔的可想像空间,可拓宽人类认知范围,不仅可再现真实存在的环境,也可以随意构想客观不存在的甚至是不可能发生的环境。30\n如可以在虚拟现实中构造另一种轻松快乐的氛围,使患者在训练时如同进入梦境一般,本文尚未对该特征进行利用。2.2VisualC++6.0中MFC概况2.2.1MFC基础MFC,微软基础类(MicrosoftFoundationClasses),同VCL类似,是一种应用程序框架,随微软VisualC++开发工具发布。该类库提供一组通用的可重用的类库供开发人员使用【14】。MFC中的类可划分为两类:CObject派生类和非CObject派生类。CObject派生类包括基类CObject,应用程序结构类和窗口类,异常类,文件相关类,绘图相关类,打印类,数据库类,网络相关类,数组、列表和印象类。非CObject派生类包括OLE类,支持类,模板收集类,基本数据类,结构类和同步类。本系统所采用的类主要有应用程序结构和窗口类。应用程序结构类主要包括命令相关类(CCmdTarget)、窗口类(CWnd)、文档类(CDocument)、视图类(CView)、框架窗口类(CFrameWnd)、文档模板类(CDocTemplate)、线程基类(CWinTHread)和窗口应用程序类(CWinAPP)等。图2-1列出了应用程序结构类的基本结构。图2-1应用程序结构类的基本结构文档类(CDocument)用于应用程序数据的管理。文档模板类(CDocTemplate)用于创建文档、视图和框架。30\n线程基类(CWinTHread)提供所有与线程有关的基本操作,可直接使用。窗口应用程序类(CWinAPP)是CWinTHread的间接子类,封装了应用程序初始化、运行、终止等代码。框架窗口类(CFrameWnd)是SID应用程序主框架窗口的基类。视图类(CView)用于显示文档数据并接受用户输入数据,是本次设计必不可少的,也是选择用MFC编程完成本系统设计的主要原因之一。对话框类(CDialog)支持对话框的全部公共操作,其子类主要包括对话框颜色选择、文件选择、字体选择等。由于Windows操作系统自身的复杂性和WindowsAPI所涉及领域的广泛性,面向对象语言C++的重要性得以充分体现。然而,直接针对WindowsAPI进行程序设计有一定的难度,且工作量较大,非常多的C++用户逐渐选择了使用MFC类库,因为MFC类库的一个最重要的特点就是体现了对WindowsAPI的封装,使得Windows应用程序开发更加简明快捷,此外,MFC作为应用程序框架,为Windows应用程序提供了标准化的结构,用户只需向框架结构内添加实现特殊功能的代码,而不必担心框架程序的编写。MFC的这一特性在为用户带来了巨大方便的同时,也使基于MFC的Windows应用程序结构更为清晰,代码更为有效。2.2.2MFC程序结构通过VisualC++6.0应用程序向导(ApplicationWizard)可以很容易地生成一个MFC应用程序基本框架,本系统只需使用MFC单文档程序即可,用户只需在此基础上添加特定的代码便可以实现预期的功能。通过AppWizard生成的类包括CExTestApp、CExTestDoc、CExTestView、CMainFrame,他们分别派生于类CWinApp、类CDocument、类CView和类CFrameWnd,又分别生成应用程序对象、文档对象、视图对象和框架窗口对象。应用程序类CExTestApp用于创建应用程序对象,基于框架的应用程序必须有且只有一个应用程序对象,它负责应用程序的初始化、运行和结束。在ExTest.cpp中用如下语句进行了实例化。CExTestApptheApp;在ExTest.h中对类CExTestApp进行了声明,如下所示。classCExTestApp:publicCWinApp{public:CExTestApp();public:virtualBOOLInitInstance();//为应用程序提供初始化afx_msgvoidOnAppAbout();30\nDECLARE_MESSAGE_MAP();};其中InitInstance的定义在ExTest.cpp中,以下代码是函数InitInstance创建文档模板对象并把它添加到应用程序的模板链表。CSingleDocTemplate*pDocTemplate;pDocTemplate=newCSingleDocTemplate(IDR_MAINFRAME,RUNTIME_CLASS(CMyOPGLDoc),RUNTIME_CLASS(CMainFrame),/RUNTIME_CLASS(CMyOPGLView));AddDocTemplate(pDocTemplate);文档模板创建完毕,接着由文档模板创建文档对象、视图对象和框架窗口对象,以下代码实现了该功能。CCommandLineInfocmdInfo;ParseCommandLine(cmdInfo);if(!ProcessShellCommand(cmdInfo))returnFALSE;窗口创建完成之后,函数InitInstance通过调用函数ShowWindow和UpdateWindow来显示窗口,如下所示。m_pMainWnd->ShowWindow(SW_SHOW);m_pMainWnd->UpdateWindow();returnTRUE;文档类CExTestDoc用来管理数据,数据的变化、存取都是通过文档实现的,并且,视图窗口通过文档对象来访问和更新数据,它提供的方法主要有构造方法、操作方法和虚拟方法。构造方法用于创建CExTestDoc类,函数声明如下。CExTestDoc();而操作方法和虚拟方法中OnNewDocument用于创建文档,AssertValid()主要是通过定义自己的规则,如一些表达式,来判断对象的有效性,Dump()主要提供一些debug信息。视图类CExTestView在文档和用户之间起中介作用,通过视图类在屏幕上显示文档的内容,并把用户输入转换成对文档的操作。CExTestView中最重要的就是OnDraw函数,主要完成文档的绘制工作,其代码如下。voidCExTestView::OnDraw(CDC*pDC){CExTestDoc*pDoc=GetDocument();30\nASSERT_VALID(pDoc);RenderScene();}视图是将文档中的数据以某种形式向用户呈现,所以每一个文档可以有多个视图,但每个视图只能对应一个确定的文档。视图类的数据成员m_pDocument保存了指向对应文档的指针,视图就通过函数GetDocument获取m_pDocument中的文档对象指针,其代码如下。CExTestDoc*CExTestView::GetDocument(){ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CExTestDoc)));return(CExTestDoc*)m_pDocument;}框架窗口类CMainFrame用于创建客户子窗口、菜单、工具栏和状态栏,为用户提供与应用程序交互的界面。类CFrameWnd提供的方法包括构造方法、初始化方法、操作方法和虚拟方法。构造方法用于创建CFrameWnd类对象,函数声明如下。CFrameWnd();实际操作中经常使用的是类的初始化方法,OnCreate函数用于创建并初始化Windows框架窗口,其代码如下intCMainFrame::OnCreate(LPCREATESTRUCTlpCreateStruct){if(CFrameWnd::OnCreate(lpCreateStruct)==-1)return-1;if(!m_wndToolBar.CreateEx(this,TBSTYLE_FLAT,WS_CHILD|WS_VISIBLE|CBRS_TOP|CBRS_GRIPPER|CBRS_TOOLTIPS|CBRS_FLYBY|CBRS_SIZE_DYNAMIC)||!m_wndToolBar.LoadToolBar(IDR_MAINFRAME)){TRACE0("Failedtocreatetoolbar\n");return-1;//failtocreate}if(!m_wndStatusBar.Create(this)||!m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT))){TRACE0("Failedtocreatestatusbar\n");return-1;//failtocreate30\n}m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);EnableDocking(CBRS_ALIGN_ANY);DockControlBar(&m_wndToolBar);return0;}PreCreateWindow函数主要功能是注册窗口类,其代码如下。BOOLCMainFrame::PreCreateWindow(CREATESTRUCT&cs){if(!CFrameWnd::PreCreateWindow(cs))returnFALSE;returnTRUE;}此外,应用程序框架的建立还依靠文档模板类,应用程序通过文档模板类对象来管理应用程序对象、文档对象、视图对象和框架窗口对象的创建。综上所述,应用程序在启动之前就创建了唯一的应用程序对象,应用程序对象创建文档模板对象,文档模板对象创建文档对象和框架窗口对象,框架窗口对象创建视图对象,具体流程如图2-2所示。应用程序对象包含一个文档模板列表,用于存放文档模板对象;文档模板对象包含一个打开文档列表,用于存放已经打开的文档对象;文档对象包含一个视图列表,用于存放显示该文档数据的视图对象,还包含一个指向创建该文档的文档模板对象的指针;框架窗口对象包含一个指向其当前活动的视图的指针;视图是一个子窗口,它还包含一个指向其关联文档的指针。图2-2应用程序各对象的创建顺序30\n2.2.3MFC应用程序运行机制Windows程序的进入点是WinMain函数,而不是main函数,应用程序执行时,Windows自动调用应用程序框架内部的WinMain函数,WinMain函数主要完成注册窗口类、建立窗口以及完成其他初始化工作;创建消息循环,根据消息类型调用相应处理函数;检索到退出消息时关闭窗口,终止程序运行。WinMain函数会查找应用程序的一个全局对象,这个对象由CWinApp派生类构造,且只有一个,之后,WinMain函数将调用这个对象的InitInstance成员函数,完成应用程序的初始化工作,接着,WinMain函数调用Run函数,运行应用程序的消息循环,最后,WinMain函数调用ExitInstance函数,退出应用程序。2.3OpenGL概况2.3.1OpenGL特点和功能ODenGL实际上是一个开放的三维图形软件包,它独立于窗口系统和操作系统,以它为基础开发的应用程序可以十分方便地在各种平台间移植:OpenGL可以与VisuaIc++紧密接口,便于实现机械手的有关计算和图形算法,可保证算法的正确性和可靠性;OpenGL使用简便,效率高【15】。它具有七大功能:1)建模OpenGL图形库除了提供基本的点、线、多边形的绘制函数外,还提供了复杂的三维物体(球、锥、多面体、茶壶等)以及复杂曲线和曲面绘制函数。2)变换OpenGL图形库的变换包括基本变换和投影变换。基本变换有平移、旋转、变比镜像四种变换,投影变换有平行投影(又称正射投影)和透视投影两种变换。其变换方法与机器人运动学中的坐标变换方法完全一致,有利于减少算法的运行时间,提高三维图形的显示速度。3)颜色模式设置OpenGL颜色模式有两种,即RGBA模式和颜色索引(color1ndex)。4)光照和材质设置OpenGL光有辐射光(EmittedLight)、环境光(AmbientLight)、漫反射光(DimseLight)和镜面光(specularLight)。材质是用光反射率来表示。场景(sccne)巾物体最终反映到人眼的颜色是光的红绿蓝分量与材质红绿监分量的反射率相乘后形成的颜色。5)纹理映射利用OpenGL纹理映射功能可以十分逼真地表达物体表面细节。6)位图显示和图象增强30\n图像功能除了基本的拷贝和像素读写外,还提供融合(Blending)、反走样(Anti-aliasing)和雾(fog)的特殊图像效果处理。以上三条可是被仿真物更具真实感,增强图形显示的效果。7)双缓存动画双缓存即前台缓存和后台缓存,简而言之,后台缓存计算场景、生成画而,前台缓存显示后台缓存已画好的画而。此外,利用OpenGL还能实现深度暗示(Depthcue)、运动模糊(MotionBlur)等特殊效果。从而实现了消隐算法。2.3.2OpenGL图形库OpenGL图形库一共有lOO多个函数。其中核心函数有115个,它们是最基本的函数,其前缀是91,OpenGL实用库(GLu)的函数功能更高一些,如绘制复杂的曲线曲面、高级坐标变换、多边形分割等,共有43个,前缀为glu;OpenGL辅助库(OpenGLauxiliarylibrary,GLAux)的函数是一些特殊的函数,包括简单的窗口管理、输入事件处理、某些复杂三维物体绘制等函数,共有31个,前缀为aux。此外,还有六个wGL函数非常重要,专门用于OpenGL和windows95窗口系统的联接,其前缀为wgl,主要用于创建和选择图形操作描述表crendering—contexts)以及在窗口内任意位置显示字符位图。这些功能是windows95对OpenGL的唯一补充。另外,还有些个win32函数用来处理像素格式(pixelformats)和双缓存。由于它们是对win32系统的扩展,因此不能应用在其它OpenGL平台上。2.3.33DS文件格式3DS文件由许多块(chunk)组成,一个块由块信息和块数据组成。块的前两项信息分别是对块ID和块的长度(也是下一个块相对于该块的字节偏移量),块的ID是一个整型数,块的长度是一个长整型数。每个块是一个层次结构,不同类型的块,其层次结构也不相同。3DS文件中有一个基本块,其ID是4D4D,它包含了整个文件,每个3DS文件的开头都是由一个这样的块构成的。基本块中的字块是3D编辑程序和关键帧块,前者的ID是3D3D,后者的ID是B000.3D编辑程序块表面编辑程序数据开始,即物体的形体数据从此处开始。关键帧块表明下面开始定义关键帧信息。3DS格式文件的读入可以分为两大部分:文件内容的读入和3D对象的绘制。2.3.4基于OpenGL的图形变换技术图形变换是计算机图形学的基础性内容。图形变换体现和展示各种事物的运动与变化的过程及其相互的连接关系【16】30\n。实际上计算机图形学的中心问题就是在一个二维的平面上来创建三维物体,因此在构图时需要在三维坐标系中进行思考。应当在三维空间中建立所绘制物体的模型,由计算机经过恰当的变换,将三维坐标系中的点转换为屏幕上的像素位置,从而得到理想的视觉效果。图形变换涉及的知识面相当广泛,这里只介绍基本的内容。要将欧氏空间的形体(在OpenGL编程系统中称之为模型)在计算机屏幕上显示出来,有以下几种方法:视图变换:相当于照相时选定相机位置并对准场景。模型变换:对应于照相时使场景处于取景框中的合适位置,即取景。投影变换:类似于选择相机镜头和调整放大倍数,即聚焦。视区变换:等价于缩放处理以得到不同尺寸的照片。所谓模型变换,指的是以一个形体(为了和OpenGL图形系统的实现保持一致,有时也将它称为模型,这与图形、形体等表示的是同一概念)作为考察对象而研究它相对于一个静止的坐标系所发生的平移、旋转、缩放等几何交换。下面给出三类基本模型变换的对应的库函数。任何变换都可以分解为有限序列的基本变换。有了这些库函数之后,图形变换的编程将显得异常简单而有效:程序员只要通过调用变换函数以正确的顺序给出变换矩阵,相应的变换会由OpenGL自动完成。1)平移变换voidglTranslate{f/d}(TYPEx,TYPEy,TYPEz);表示把当前矩阵与一个表示移动的矩阵相乘,x,y,z表示在坐标系统中在各个轴上移动的量,f和d表示数据类型。2)旋转变换voidglRotate{f/d}(TYPEangle,TYPEx,TYPEy,TYPEz);表示把当前矩阵与一个表示旋转的矩阵相乘,以逆时针方向绕着从原点到点(x,y,z)的直线进行旋转,angle参数指定了旋转的角度。3)缩放变换voidglScale{f/d}(TYPEx,TYPEy,TYPEz);表示把当前矩阵与一个表示沿着各轴对物体进行拉伸、收缩或反射的矩阵相乘。x,y,z的值表示在各个轴上拉伸、收缩或反射的比例。视图变换实际上就是为经过模型变换的模型选择合适的观察点(视点)。在拍摄相片的过程中,类似视图变换的操作就是选择相机的位置和对准景物(选择拍摄方向),而在图形显示中,就是选择观察者眼睛的位置、角度和朝向。其实,视图变换与模型变换完全是等价的,只是着眼点不同而己。比如,一个模型在坐标系中朝远离视点的方向进行平移的模型变换,完全可以认为模型不动而通过将视点朝相反的方向进行平移这样的视图变换来达到目的。对于缩放和旋转模型变换也有类似的情况。OpenGL系统的各种模型变换函数同样也可以用于进行视图变换。在有些时候,甚至不必理会视图变换而只进行模型变换,并让视点处在默认的原点位置与指向Z轴的负向。基于同样的原因,OpenGL将模型变换与视图变换看作同一类变换,而称之为模型视图变换。利用OpenGL库函数进行这类变换之前,30\n首先要调用一个函数glMatrixMode(GL_MODELVIEW)将后续的变换指定为针对模型进行的模型视图变换。当然,为了某些特定的需要,OpenGL系统也提供函数gluLookAt0用于指定视点,其参数分别是视点位置坐标以及视线在模型上入射点(着眼点)的位置坐标。由于投影变换和视区变换在本文中未应用到,在此不作详细的解释。2.3.5VC++调用OpenGL简介VC++下生成OpenGL程序的基本步骤为(基于MFCAppWizard):1)首先创建工程;2)将此工程所需的OpenGL文件和库加入到工程:3)编写要创建函数;4)编写销毁函数、消除位图、定时器等资源及设备场景等:5)修改CView类的样式;6)编写OnDraw事件处理代码:7)在OnSize方法中定义当前视区、投影模型和物体模型以及光源等:8)编写OnTimet事件处理程序;9)编写OpenGL绘制程序。GDI是通过设备句柄(DeviceContext以下简称DC)来绘图,而在具体的实现过程中,OpenGL则需要绘制环境(RenderingContext,以下简称PC)完成三维图形的绘制。每一个GDI命令需要传给它一个DC,与GDI不同,OPENGL使用当前绘制环境(RC)。在一个线程中指定了一个当前RC后,所有在此线程中的OPENGL命令都使用相同的当前RC。虽然在单一窗口中可以使用多个RC,但在单一线程中只要一个当前RC【3】。在VC++中,绘图需要DC,而OPENGL编程环境中,需要使用RC。两者并不相同,它需要在由产生RC的DC句柄指定设备上绘图。绘图时,要先初始化定义DC的象素格式,然后用wglCreateContext函数创建一个RC,并用wglMakeCurrent函数把它作为当前线程的RC,最后调用OPENGL函数在指定设备上绘图,绘图结束后,将它释放。概括为:设置窗口象素格式:产生RC;设置为当前RC。3系统方案规划3.1下肢模型建模方法设计本系统的首要工作就是得到一个膝盖以下的三维下肢模型,下肢模型的绘制方法有很多。1)利用OpenGL函数绘制OpenGL30\n实用库的函数能够提供绘图功能,如绘制复杂的曲线曲面、高级坐标变换、多边形分割等,它虽然可免除模型的导入这一步骤,但是该方法完全靠程序编写完成,整个绘制过程中看不到每一步绘制的结果,而且绘制的过程较复杂,工作量大对于初学者和非计算机图形专业的学生难度较大,需要有较强的空间想象能力,故本次设计不采用该方法1)采用绘图软件绘制网上的绘图软件各式各样,有CAD、Rhino、CATIA、PRO/E、UG、3DSMAX等,其中3DSMAX是Autodesk公司开发的基于PC系统的三维动画渲染和制作软件。具有功能强大,扩展性好;操作简单,容易上手;和其它相关软件配合流畅;效果逼真等优点,它所生成的3DS文件已经成为业界的标准,是一种非常普及的数据格式,能够利用OpenGL导入到VisualC++6.0中,故本次设计选用3DSMAX绘制下肢模型3.2运动控制方法下肢模型的运动控制方法有很多,有关键帧方法,运动学方法,动力学方法,运动捕捉方法和过程动画方法[17]。1)关键帧方法关键帧技术是进行虚拟人运动控制的最早方法,也是控制虚拟人运动细节最早的方法。在早期的卡通动画制作过程中,先由高级动画师设计关键帧,然后由助理动画师设计中间帧。计算机图形学的发展,中间帧可以采用计算机自动生成,使插补取代了设计中间帧的艺术家。由于关键帧技术最初仅仅是用来插值的帧与帧之间卡通画的形状。后来,该技术被发展成为可以用来插值影响运动的任何参数,因此,也称其为参数关键帧。关键帧技术要求动画师除具有设计关键帧的技能外,还要特别清楚运动对象关于时间的行为,较为复杂,所以本文不采取该方法2)过程动画方法过程动画(ProceduralMethods)指的是用一个过程去控制物体的动画。通过使用这种方法,动画师只需要明确一小部分的参数(例如速度、行走的步长等),通过一个具体的过程就可以计算出每一时刻的姿势以及下一个时刻即将出现的运动画面。过程动画技术的优越性主要体现在三个方面:可以根据人体特征及运动特征确定人体运动,很容易生成一系列相似的运动,具有较好的逼真性能:过程动画技术使用了大量的经验公式,降低了系统复杂性,可以很方便的生成一些非常复杂的系统和群体运动;过程动画技术具有生成交互行为的潜力。过程动画技术也有一定的局限性。首先,利用过程动画很难定义一般的运动,它只适用于某些特定类型的运动。其次,动画师不能在动画中进行很好的细节上的控制,因此也导致了角色动画运动缺乏表情或独特性。2)运动捕捉方法30\n运动捕获技术是通过使用传感器来记录运动者的运动信息,它也是目前在商业产品中比较常用的一种生成运动的技术。运动捕获技术可以利用记录下来的数据产生动画运动,也可以用一种带有关节传感器的木偶来代替真人。运动捕获是目前相当流行的一种技术,主要是因为它可以很容易的获得许多人体运动的数据,生成的人体运动基本上是主体人运动的复制品,效果十分生动形象逼真。然而,也存在很多问题制约着这一技术的发展和应用。首先,在运动捕获中,附着在运动者皮肤或是衣服上的跟踪器在运动时会产生一定程度的移位,造成运动数据有一定的冗余,在某些情况下,还会引起虚拟人的运动失真。其次,一些用于捕获运动的技术本身具有局限性,导致一些运动不钱被捕获。一些传感器是磁的,而且金属会对捕获的数据产生一定的干扰。还有一些传感器要求被捕获者连到计算机上,因此限制了被捕获者的运动。另外一些传感器是光学的,这类传感器在使用时,容易使被捕获者身体的运动数据混淆。尽管运动捕获技术中还存在一些不足,但是鉴于运动捕获技术可以自动的捕获人体运动的细节,这项技术仍然得到了广泛的应用。1)运动学方法正向和逆向运动学是设置虚拟人关节运动的有效方法。正向运动学是把末端效应器(如手或脚)作为时间的函数。关于固定参考坐标系,求解末端效应器的位置,而与引起运动的力和力矩无关。一个行之有效的方法是把位置和速度从关节空间变换到笛卡尔坐标系。参数关键帧动画是正向运动学的最初应用,通过插入对应正向运动学的关键关节角来驱动关节肢体的运动。对于一个具有多年经验的专家级动画师,能够用正向运动学方法生成非常逼真的运动,但对于一个普通的动画师来说,通过设置各个关节的关键帧来产生逼真的运动是非常困难的。逆向运动学方法在一定程度上减轻了正向运动学方法的繁琐工作。用户通过指定末端关节的位置,计算机自动计算出各中间关节的位置,即关节角是自动确定的。这是个关键问题,因为虚拟人的各独立变量就是关节角。但是,从笛卡尔到关节坐标的位置变换一般没有唯一解。为此,人们对关节轴进行了大量的特殊安排,以便在动画进行过程中得到唯一解。基于运动学的系统一般直观而缺乏完整性,它没对基本的物理事实如重力、惯性等做出响应。综上各方法各自都有优越性和局限性,但是本文所涉及的系统对运动的精确度要求不高,只要求能够观察到各种运动状态即可,所以本文采用改进的运动学方法,即控制模型的每一块的坐标变化来达到运动的目的。30\n4系统实现4.1下肢模型建模首先创建一个立方体,通过编辑立方体的各个面,对其进行拉伸、平滑等处理构造出下肢骨骼模型的雏形,再利用修改器对模型进行细化和细节修改【18】,最终所得模型如图4-1.图4-1下肢模型由于在3DSMAX中所画模型是以max的格式保存的,要用OpenGL技术导入VisualC++6.0必须导出模型,以3DS的格式保存。4.2创建一MFC单文档工程在VisualC++6.0下创建一MFCAppWizard(exe)单文档工程,在MyOPGLView.cpp首先添加OnCreate函数,用于消息响应,其代码如下。intCMyOPGLView::OnCreate(LPCREATESTRUCTlpCreateStruct){if(CView::OnCreate(lpCreateStruct)==-1)return-1;m_pDC=newCClientDC(this);SetTimer(1,20,NULL);//创建一个定时器InitializeOpenGL(m_pDC);//初始化文件和基类框架Init();//初始化return0;30\n}OnCreate()不产生窗口,只是在窗口显示前设置窗口的属性如风格、位置等。其中的SetTimer函数用于创建或设置一个定时器,该函数创建的定时器与Timer控件(定时器控件)效果相同。当你想每隔一段时间执行一件事的的时候,你可以使用它。使用定时器的方法比较简单,通常告诉WINDOWS一个时间间隔,然后WINDOWS以此时间间隔周期性触发程序。通常有两种方法来实现:发送WM_TIMER消息和调用应用程序定义的回调函数。SetTimer(1,20,NULL);表示采用计时器1,每隔20ms调用回调函数OnTimer。该函数主要用于键盘扫描,能够实时反映输入信息并作出响应。然后添加销毁函数OnDestroy,OnDestroy函数从真正意义上销毁窗口,销毁所有内存空间和定时器,防止出现内存泄漏,其代码如下。voidCMyOPGLView::OnDestroy(){CView::OnDestroy();::wglMakeCurrent(0,0);::wglDeleteContext(m_hRC);if(m_hPalette)DeleteObject(m_hPalette);if(m_pDC){deletem_pDC;}KillTimer(1);}接着就是添加OnSize函数,定义当前视区、投影模型和物体模型以及光源等。代码如下所示voidCMyOPGLView::OnSize(UINTnType,intcx,intcy){CView::OnSize(nType,cx,cy);glViewport(0,0,cx,cy);//可以对窗口区域进行划分,在同一个窗口中显示分割屏幕的效果,以显示多个视图GLdoubleaspect_ratio;aspect_ratio=(GLdouble)cx/(GLdouble)cy;::glMatrixMode(GL_PROJECTION);//指定哪一个矩阵是当前矩阵::glLoadIdentity();//重置当前指定的矩阵为单位矩阵gluPerspective(40.0F,aspect_ratio,1.0F,10000.0F);//透视投影矩阵::glMatrixMode(GL_MODELVIEW);::glLoadIdentity();30\n}最后,就是添加设置像素和调色板的函数了,即SetupPixelFormat函数和SetLogicalPalette函数,这两个函数的代码在所有程序中均差不多,在此不作详细介绍,详细可查阅文献【16】。到此为止,MFC程序设计基本完成,即完成了显示窗口的设定,下一节将介绍模型的导入。4.33DS文件的读入根据3DS文件的结构定义,采用面向对象技术,把3DS文件对3D模型的描述信息进行数据抽象,首先定义一系列的结构,用来存放对象的材质、位置矢量、关键帧等,然后定义用于处理3DS文件中各种对象的TriObject类和处理对象序列的TriList类【19】。TriObject类中包含对象的几何坐标位置(x,y,z),对象的法向量(nx,ny,nz),对象的面faces,对象的材质materials,对象的名称name等成员变量,主要对对象的参数进行处理,并判断各参数是否正常。TriObject类和TriList类主要是用于存储对象信息的,所以还必须有一个3DS文件的读入类C3dsReader,主要将3DS文件中的内容读入到上述两个对象中。C3dsReader类中有很多成员函数,用于读取不同的内容,主要有以下几个://将块的内容读入块结构中intC3dsReader::Read3DSChunk(FILE*fp,Chunk3DS&chunk)//读入字符串,如果字符串的长度大于缓冲区,则截去多余的部分intC3dsReader::Read3DSString(FILE*fp,char*name,intlen/*=256*/)//读入子块intC3dsReader::ReadPercentage(FILE*fp,float&value)//读入颜色定义intC3dsReader::ReadColor(FILE*fp,float&red,float&green,float&blue)//读入顶点intC3dsReader::ReadPointArray(CTriObject*newchild,longfileSize,FILE*fp)//读入多边形intC3dsReader::ReadFaceArray(CTriObject*newchild,longunsignedfileSize,FILE*fp)//读入对象所用的材质intC3dsReader::ReadMeshMatGroup(CTriObject*newchild,MaterialDict*matdict,longfileSize,FILE*fp)//读入对象数据30\nintC3dsReader::ReadTriObject(MaterialDict*matdict,longfileSize,FILE*fp,longtriStart,longtriSize,char*groupName)/读入对应名称的对象块,其它名称的块将忽略intC3dsReader::ReadNamedObject(MaterialDict*matdict,longfileSize,longnamedStart,longnamedSize,FILE*fp)//读入材质定义,并将其添加到材质库中intC3dsReader::ReadMatEntry(MaterialDict*matdict,longfileSize,longmatStart,longmatSize,FILE*fp)//读入3DS文件intC3dsReader::Read3DSFile(longfileSize,longfileStart,longfileLen,FILE*fp)4.43D对象的绘制通过C3dsReader类把3DS文件的信息读入到TriObject类的对象中,对象的绘制就是根据TriObject类中保存的信息,用OpenGL绘图命令绘制出来的,这个工作主要由TriObject类的成员函数drawGL完成。对象的外部形状主要是采用三角形来近似的,并通过OpenGL赋予对象材质和纹理等效果。绘图的代码如下。voidCTriObject::drawGL(){if(normalapplied){intj;glBegin(GL_TRIANGLES);for(i=0;i