概述
文章来源:http://www.zwqxin.com/archives/opengl/3ds-cload3ds-view-2.html
CLoad3DS类是Sourceforge中的一个开源项目,作用在于帮助开发者学会简单的对3DS文件的载入(OpenGL)程序。虽然有更成熟更强大的3dslib库,但是平时写写Demo中,对模型载入的要求一般比较低,这时候只把CLoad3DS类包含到程序就够了。——ZwqXin.com 本文承接上篇文章:一个读取3DS文件的类CLoad3DS浅析Ⅰ 。
本文来源于 ZwqXin (http://www.zwqxin.com/), 转载请注明
原文地址:http://www.zwqxin.com/archives/opengl/3ds-cload3ds-view-2.html
上文提到,ProcessNextChunk(&Model3DS, m_CurrentChunk)这个函数做了模型载入部分最重要的东西。
- // 下面的函数读出3ds文件的主要部分
- //注意传入的后一个参数是刚被ReadChunk过的m_CurrentChunk,也就是说它从0x4D4D块(树干)后开始继续处理,并把0x4D4D块作为pPreviousChunk(前一个块)
- //处理树结构的常用手法就是递归
- void CLoad3DS::ProcessNextChunk(t3DModel *pModel, tChunk *pPreviousChunk)
- {
- ..........
- m_CurrentChunk = new tChunk; // 为新的块分配空间
- //因为父块的length是子块length总和,而又由0x4D4D块开始,故这个while会遍历整个3DS文件数据
- //然后我们在“case OBJECTINFO”中找到了递归,因为OBJECTINFO(0x3D3D,3D editor chunk)就是父块0x4D4D的最直接子块,这次递归中的ProcessNextChunk函数中,while中的pPreviousChunk是递归前(上一层)的m_CurrentChunk,因此switch中寻觅的将是上一层所进入的这个OBJECTINFO块下的子块(找到MATERIAL或OBJECT来处理直至该OBJECTINFO的递归完结,回来继续0x4D4D下的寻觅)。
- //总觉得说着说着自己也蒙蒙的(这就是递归!),事实上EDITKEYFRAME跟OBJECTINFO是同级的,不过我们本来就没用到EDITKEYFRAME这种块,故遇到它只是略过(单纯用它所“拥有”的length来增加0x4D4D的bytesRead)
- //总之呢,你打开某杀毒软件从“我的电脑”开始杀一次毒,观察一下查杀顺序能加深理解恩
- while (pPreviousChunk->bytesRead < pPreviousChunk->length)
- {
- ReadChunk(m_CurrentChunk);// 读入下一个块
- switch (m_CurrentChunk->ID)
- {
- case VERSION: ... // 文件版本号
- break;
- case OBJECTINFO: .... // 网格对象信息(3D editor chunk)
- ProcessNextChunk(pModel, m_CurrentChunk);//!!!
- break;
- case MATERIAL: .... // 材质信息
- break;
- case OBJECT: .... // 对象的名称
- break;
- case EDITKEYFRAME: .....
- break;
- default:
- // 跳过所有忽略的块的内容的读入,增加需要读入的字节数
- m_CurrentChunk->bytesRead += fread(buffer, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);
- break;
- }
- // 增加从最后块读入的字节数
- pPreviousChunk->bytesRead += m_CurrentChunk->bytesRead;
- }
- // 释放当前块的内存空间
- delete m_CurrentChunk;
- m_CurrentChunk = pPreviousChunk;
- }
case语句中的处理函数随chunk的ID(种类)不同而不同,但这些处理函数多少也是递归函数。分配存储空间后,从文件读入后存入相应的数据结构中,并增加该chunk的bytesRead。最需要注意的是,一般由3DS MAX导出的3ds文件的模型坐标跟OPENGL中不同,在读入顶点时要处理(swap)一下。
- // 读下一个块
- void ProcessNextChunk(t3DModel *pModel, tChunk *);
- // 读下一个对象块
- void ProcessNextObjectChunk(t3DModel *pModel, t3DObject *pObject, tChunk *);
- // 读下一个材质块
- void ProcessNextMaterialChunk(t3DModel *pModel, tChunk *);
- // 读对象颜色的RGB值
- void ReadColorChunk(tMaterialInfo *pMaterial, tChunk *pChunk);
- // 读对象的顶点
- void ReadVertices(t3DObject *pObject, tChunk *);
- // 读对象的面信息
- void ReadVertexIndices(t3DObject *pObject, tChunk *);
- // 读对象的纹理坐标
- void ReadUVCoordinates(t3DObject *pObject, tChunk *);
- // 读赋予对象的材质名称
- void ReadObjectMaterial(t3DModel *pModel, t3DObject *pObject, tChunk *pPreviousChunk);
另外还有读入字符串,各种向量等通用计算函数等等,就不介绍了。在ImportModel的第4步中,要计算顶点法向量(把以该点为顶点的各个面的法向量取均值),貌似3DS文件中没有保存法向量信息的chunk吧。因此这里导入的模型要重新(粗略地)计算面和顶点法向量。
最后是DrawModel绘制模型(集齐了顶点,纹理或材质[难道有了纹理就不能用材质吗,汗一个],顶点法向量,用三角面片方式按索引绘制),并在RenderModel中调用并作移转缩等处理。总结一下:CLoad3DS类最核心的就是递归思想,以及它与3DS文件树型结构的对应。
CLoad3DS类下载:点此。
本文来源于 ZwqXin (http://www.zwqxin.com/), 转载请注明
原文地址:http://www.zwqxin.com/archives/opengl/3ds-cload3ds-view-2.html
最后
以上就是微笑诺言为你收集整理的一个读取3DS文件的类CLoad3DS浅析Ⅱ的全部内容,希望文章能够帮你解决一个读取3DS文件的类CLoad3DS浅析Ⅱ所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复