3D模型(.x)

2D游戏中的精灵和建筑的都是美术们预先画好的图片,那么3D中是什么呢?答案是‘模型’,是3DMAX或是MAYA做出来3D模型,模型中存储了顶点的位置、面的组成、顶点的纹理坐标、材质和贴图等等我们需要的信息。一般的3D游戏都有自己的模型格式,D3D也有一种模型格式,那就是.x文件。
  
D3D已经为我们做好.x文件的支持,所以使用起来非常的方便,只需要简单的几条函数就可以把一个模型渲染出来了。如果你不去写3D导出插件,那么我们可能永远也不需要了解.x的文件格式,但是我们必须了解.x是怎么做出来的:

  1、              
在3DMAX中建立模型。
  2、              
导出为*.3ds格式。
  3、              
使用D3D提供的conv3ds.exe工具就可以把*.3ds格式的文件转化成.x文件。
  (conv3ds.exe在Dx8sdk中有提供,在本回的例子程序包中也有一份^_^)

  OK,现在.x文件也有了,开始写程序吧。

  先要使用D3D给我们提供的模型接口定义一个模型的指针出来。


  LPD3DXMESH          g_pMesh        = NULL;  // 模型对象指针

  D3DMATERIAL8*       g_pMeshMaterials = NULL; // 模型的材质数组(一个模型可以有多个材质)
  LPDIRECT3DTEXTURE8* g_pMeshTextures = NULL; // 模型的纹理数组(一个模型可以有多个纹理)
  DWORD               g_dwNumMaterials = 0L;  // 材质的数量(等于纹理数量)


一、
接着就是从.x文件读入我们的模型。

  // 材质缓冲
  LPD3DXBUFFER pD3DXMtrlBuffer;

  // 读入tiger.x到我们的模型
  if( FAILED( D3DXLoadMeshFromX(
            "Tiger.x",              // [输入].x文件名
            D3DXMESH_SYSTEMMEM,     // [输入]使用系统内存
            g_pd3dDevice,           // [输入]d3d设备指针
            NULL,                   // 不用管
            &pD3DXMtrlBuffer,       // [输出]获取模型的材质缓冲
            &g_dwNumMaterials,      // [输出]材质的数量
            &g_pMesh ) ) )          // [输出]模型对象指针
  {
    return E_FAIL;
  }


三、遗憾的是D3DXMESH并没有为什么提供模型的材质和纹理管理,所以必须自己做这件事情。

    // 获取材质指针

  D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->  GetBufferPointer();
  g_pMeshMaterials = new D3DMATERIAL8[g_dwNumMaterials];
  g_pMeshTextures  = new LPDIRECT3DTEXTURE8[g_dwNumMaterials];

  for( DWORD i=0; i<g_dwNumMaterials; i++ )
  {
       // 把需要的材质拷贝到我们的材质对象中
       g_pMeshMaterials[i] = d3dxMaterials[i].MatD3D;

       // 为材质设置环境色
       g_pMeshMaterials[i].Ambient = g_pMeshMaterials[i].Diffuse;

  
     // 创建对应的纹理
       if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice,
                                                d3dxMaterials[i].pTextureFilename,
                                                &g_pMeshTextures[i] ) ) )
       {
           g_pMeshTextures[i] = NULL;
       }
  }

  // 释放缓冲
  pD3DXMtrlBuffer->Release();


四、一切准备就绪,渲染吧。要注意,在.x文件被读入时,模型是被切分了的,每一个材质对应一部分的模型。


    // 根据材质的数量我们的模型被切分了,每个材质对应一部分
    // 所以渲染的时候也要分几个部分渲染
    for( DWORD i=0; i<g_dwNumMaterials; i++ )
    {
        // 为这一部分设置材质
        g_pd3dDevice->SetMaterial( &g_pMeshMaterials[i] );
        g_pd3dDevice->SetTexture( 0, g_pMeshTextures[i] );

        // 渲染这一部分
        g_pMesh->DrawSubset( i );
    }


  很快,程序运行的结果也出来了:

   


  一切都弄好了,是不是感到不可思议的简单?我也是这样认为,不过实际上很少看到有商业的游戏直接使用.x文件,大多数都是自己写插件,我也写过一个,不过对于大家入门来
说, .x 已经足够了。没有必要所有人都去写游戏引擎吧,你说对不对?了解3D的基本实现原理后,我想以后你去做真正的3D游戏时,心里就不会一点底都没有了。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值