• 【原创】IrrLicht中ms3D模型不支持多个贴图问题的解决


    测试过irrlicht中ms3d模型的朋友可能发现了这样的现象,如果ms3d模型只有一个贴图,则无论贴图文件放到和demo可执行程序同一目录下或者调用setMaterialTexture()函数都可以让模型正常被正常渲染,而当模型拥有两个或以上贴图时,则只有贴图和可执行程序在同一目录被自动加载时才能正确渲染,而用setMaterialTexture(0,。。。),setMaterialTexture(1,。。。)时似乎只有第一个贴图起作用。仔细查看引擎的代码发现,这不是偶然的现象,也可以算是引擎对ms3d模型支持的一个bug吧。在说到具体的解决方案之前,我们先来说一下ms3d模型中组的概念。“组”顾名思义应该是拥有一些共同属性的事物集合了。在ms3d中,一个组内的三角形就拥有同一个贴图文件。在引擎装载ms3d模型数据时,已经记下了组对应的贴图文件名,因此自动贴图不会出错。而在用setMaterialTexture函数指定时却并没有指定是哪个组的贴图,因此就会出现只有一个贴图起效果的现像,其实从代码中可以看出,它是遍历了所有组,但都用了setMaterialTexture(0,...)指定的这一个贴图。
    好了,知道原因后,我们大概就可以想到解决办法了。就是在setMaterialTexture时也指定是哪个组。对就是这样。我们提供了另外两个针对MS3D的setMaterialTexture函数,分别是:
    void  CAnimatedMeshSceneNode::setMS3DMaterialTexture(const c8 * groupName,s32 textureLayer, video::ITexture* texture)
    {
      if (textureLayer<0 || textureLayer>= video::MATERIAL_MAX_TEXTURES)
        return;

      // 根据组名得到MeshBuffer
      IMesh * pMesh = Mesh->getMesh(0,0);
      
      for(s32 i = 0; i<pMesh->getMeshBufferCount();i++)
      {
       IMeshBuffer* pMeshBuf = pMesh->getMeshBuffer(i);
       if(strcmp(pMeshBuf->getGroupName(),groupName) == 0){
        irr::video::SMaterial & mat = pMeshBuf->getMaterial();
        mat.Textures[textureLayer] = texture;
        Materials[i].Texture1 = texture;
        break;
       }
      }

    }
    void  CAnimatedMeshSceneNode::setMS3DMaterialTexture(s32 groupIndex,s32 textureLayer, video::ITexture* texture)
    {
      if (textureLayer<0 || textureLayer>= video::MATERIAL_MAX_TEXTURES)
        return;
      
     
      // 根据组名得到MeshBuffer
      IMesh * pMesh = Mesh->getMesh(0,0);
      
      if(groupIndex < 0 || groupIndex > pMesh->getMeshBufferCount())
       return;

      
      IMeshBuffer* pMeshBuf = pMesh->getMeshBuffer(groupIndex);
      // yfxu
      irr::video::SMaterial & mat = pMeshBuf->getMaterial();
      mat.Textures[textureLayer] = texture;
      if(textureLayer == 0) mat.Texture1 = texture; 
      Materials[groupIndex].Texture1 = texture;

    }
    一个是根据组名设贴图,一个是根据组索引设贴图。
    值得一起的是 引擎在载如ms3d模型数据在取组名时也有一点问题,原来的代码如下:
    for (i=0; i<numGroups; ++i)
     {
      Groups.push_back(SGroup());
      SGroup& grp = Groups.getLast();
      // 组名称
      grp.Name = (const c8*)pPt;
    。。。

    参考ms3d的文件格式可知改为:
     grp.Name = (const c8*)(pPt+1);
    才能正确取到组名。
    到此为止,加上动画模型旋转bug,和无效帧问题的解决。irrlicht对ms3d模型的支持基本就完美了。

    下图中的美女,身体和头发是分开的贴图:


  • 相关阅读:
    转(一万小时定律的文章): const 与 readonly区别...
    项目中报错邮件方法
    Windows Phone(一) 正式开发之前的准备资料(主要注册开发者账号,手机解锁,激活码,程序部署)
    转(ASP.NET页面缓存)
    部署XAP时,部署工具提示部署无效,求解决!
    jQuery 1
    DOMform
    jQuery 2 一些常用的函数
    jQuery 6 层次选择器
    jQuery 3 对象转换
  • 原文地址:https://www.cnblogs.com/flysnow/p/462093.html
Copyright © 2020-2023  润新知