一个读取3DS文件的类CLoad3DS浅析Ⅱ

文章来源: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)这个函数做了模型载入部分最重要的东西。

  1. // 下面的函数读出3ds文件的主要部分
  2. //注意传入的后一个参数是刚被ReadChunk过的m_CurrentChunk,也就是说它从0x4D4D块(树干)后开始继续处理,并把0x4D4D块作为pPreviousChunk(前一个块)
  3. //处理树结构的常用手法就是递归
  4. void CLoad3DS::ProcessNextChunk(t3DModel *pModel, tChunk *pPreviousChunk)
  5. {
  6.   ..........
  7.   m_CurrentChunk = new tChunk;        // 为新的块分配空间    
  8.  
  9. //因为父块的length是子块length总和,而又由0x4D4D块开始,故这个while会遍历整个3DS文件数据
  10.  
  11. //然后我们在“case OBJECTINFO”中找到了递归,因为OBJECTINFO(0x3D3D,3D editor chunk)就是父块0x4D4D的最直接子块,这次递归中的ProcessNextChunk函数中,while中的pPreviousChunk是递归前(上一层)的m_CurrentChunk,因此switch中寻觅的将是上一层所进入的这个OBJECTINFO块下的子块(找到MATERIAL或OBJECT来处理直至该OBJECTINFO的递归完结,回来继续0x4D4D下的寻觅)。
  12.  
  13. //总觉得说着说着自己也蒙蒙的(这就是递归!),事实上EDITKEYFRAME跟OBJECTINFO是同级的,不过我们本来就没用到EDITKEYFRAME这种块,故遇到它只是略过(单纯用它所“拥有”的length来增加0x4D4D的bytesRead)
  14. //总之呢,你打开某杀毒软件从“我的电脑”开始杀一次毒,观察一下查杀顺序能加深理解恩
  15.  
  16.   while (pPreviousChunk->bytesRead < pPreviousChunk->length)
  17.   {
  18.         ReadChunk(m_CurrentChunk);// 读入下一个块
  19.  
  20.     switch (m_CurrentChunk->ID)
  21.     {
  22.     case VERSION:       ...     // 文件版本号
  23.       break;
  24.     case OBJECTINFO:     .... // 网格对象信息(3D editor chunk)
  25.      ProcessNextChunk(pModel, m_CurrentChunk);//!!!
  26.       break;
  27.     case MATERIAL:      ....        // 材质信息
  28.        break;
  29.     case OBJECT:        ....      // 对象的名称
  30.        break;
  31.     case EDITKEYFRAME: .....
  32.       break;
  33.     default:    
  34.       // 跳过所有忽略的块的内容的读入,增加需要读入的字节数
  35.       m_CurrentChunk->bytesRead += fread(buffer, 1, m_CurrentChunk->length - m_CurrentChunk->bytesRead, m_FilePointer);
  36.       break;
  37.     }
  38.     // 增加从最后块读入的字节数
  39.     pPreviousChunk->bytesRead += m_CurrentChunk->bytesRead;
  40.   }
  41.  
  42.   // 释放当前块的内存空间
  43.   delete m_CurrentChunk;
  44.   m_CurrentChunk = pPreviousChunk;
  45. }

case语句中的处理函数随chunk的ID(种类)不同而不同,但这些处理函数多少也是递归函数。分配存储空间后,从文件读入后存入相应的数据结构中,并增加该chunk的bytesRead。最需要注意的是,一般由3DS MAX导出的3ds文件的模型坐标跟OPENGL中不同,在读入顶点时要处理(swap)一下。

  1. // 读下一个块
  2.  void ProcessNextChunk(t3DModel *pModel, tChunk *);
  3.  // 读下一个对象块
  4.  void ProcessNextObjectChunk(t3DModel *pModel, t3DObject *pObject, tChunk *);
  5.  // 读下一个材质块
  6.  void ProcessNextMaterialChunk(t3DModel *pModel, tChunk *);
  7.  // 读对象颜色的RGB值
  8.  void ReadColorChunk(tMaterialInfo *pMaterial, tChunk *pChunk);
  9.  // 读对象的顶点
  10.  void ReadVertices(t3DObject *pObject, tChunk *);
  11.  // 读对象的面信息
  12.  void ReadVertexIndices(t3DObject *pObject, tChunk *);
  13.  // 读对象的纹理坐标
  14.  void ReadUVCoordinates(t3DObject *pObject, tChunk *);
  15.  // 读赋予对象的材质名称
  16.  void ReadObjectMaterial(t3DModel *pModel, t3DObject *pObject, tChunk *pPreviousChunk);
  17.  
另外还有读入字符串,各种向量等通用计算函数等等,就不介绍了。在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文件例子 作者:野草我想做个室内渲染程序,要加载3ds室内模型,我本来不想深入研究3ds文件格式的,但是我在网上找了好几个读取3ds文件的例子,不是只能显示网格,就是只能帖一张图,要么只能读版本低的文件. 反正是找不着一个比较完善的.比如 www.gametutorials.com 上的读取3ds文件的例子就有问题,一读我用3ds max5.0 生成的3ds文件就会非法操作,而且一个物体只能帖一张图; http://www.tsrevolution.com 上的C3DS的例子只能显示网格; http://www.spacesimulator.net上能读取3ds max 5.0的文件,但也只能帖一张图.看来不研究3ds文件格式是不行的了.上提到的程序多多少少都有3ds文件格式的说明,但都是E文的了.我在这里也不想详细说3ds文件格式,我只是想,用这个的人不用知道它的格式就可以很好的用它.如果你真要研究,上的网站你可以参考一下.首先说明,这个只是把上提到的几个例子融合在一起,并作了些改进而已.不要说我抄袭别人的代码. J 只是为了方便大家.我想最好的说教莫过于例子了,于是我就在这里提供一下例子,你可以根据你的需要修改这个例子.在我的应用里模型全都有帖图.在这个例子里我假设你的模型用的都是帖图而没使用颜色,如果你的模型没有用帖图,那模型的颜色应该不是你想要的.如果你想要加载颜色又不想研究3ds文件格式,来信告诉我,我再完善它.加载3ds模型只是游戏开发的一小步,还有很多事情要做.如果你只是就像我例子里那样加载一个比较大的模型并且也像我的例子里那样显示的话,你会发现速度奇慢无比 L 加快显示速度就是你要做的第二件事.比如用Portal技术,我的另一个程序里已经实现了.如果你想要看一下效果,可以到我的网站下载Demo : http://3dbrothers.kom.cn 本地下载:Load3DSDemo.rar
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值