游戏开发论坛

 找回密码
 立即注册
搜索
查看: 6422|回复: 4

用dx API 来渲染 3ds 模型文件(新手入门级)

[复制链接]

1

主题

3

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2007-10-22 15:34:00 | 显示全部楼层 |阅读模式
3DS 文件在 Directx中渲染的实现
刚接触directx的,人经常碰到3D文件格式,无法读取的问题。在DX,SDK里只介绍了两种外部文件读取方式.x和.obj,对于.x文件dx内部有相当完善的内部接口函数,可以处理文件的读取渲染。包括实现LOD渲染,分块渲染,甚至是内置特效处理,而且速度运行极快。更重要的是。x的文件通俗易懂,所以大部分初学DX的朋友为了把别的文件格式转化到。x上来煞费了不少苦心。就我所知maya配合DX 的插件,3D MAX结合pandaX插件,Milkship等都能完成这个工作。但是有时候总会碰到无法正确转化的情况,而且对于大量的3DS文件,一个个通过软件转化实在很累,特别是被微软的基本格式束缚,绝非我愿,因此实现在DX下渲染3ds文件势在必行。可惜网上大多找到GL下渲染的实例,所以本着学习共进的思想决定动手自己来一个。

总体思路是这样的:提取3ds文件信息-〉信息模块化->建立绘图缓冲装载信息->实现渲染
首先, 建立如下结构体(来自引用部分:3DS.H 到处可以下到,而且内容大同小异,我在这里借用的是相对组织明了,简便的一个)
// 定义3D点的类,用于保存模型中的顶点
class CVector3
{
public:
  float x, y, z;
};
// 定义2D点类,用于保存模型的UV纹理坐标
class CVector2
{
public:
  float x, y;
};
// 面的结构定义
struct tFace
{
  int vertIndex[3];      // 顶点索引
  int coordIndex[3];      // 纹理坐标索引
};
// 材质信息结构体
struct tMaterialInfo
{
  char strName[255];      // 纹理名称
  char strFile[255];      // 如果存在纹理映射,则表示纹理文件名称
  BYTE color[3];        // 对象的RGB颜色
  int texureId;        // 纹理ID
  float uTile;        // u 重复
  float vTile;        // v 重复
  float uOffset;       // u 纹理偏移
  float vOffset;        // v 纹理偏移
} ;
// 对象信息结构体
struct t3DObject
{
  int numOfVerts;      // 模型中顶点的数目
  int numOfFaces;      // 模型中面的数目
  int numTexVertex;      // 模型中纹理坐标的数目
  int materialID;      // 纹理ID
  bool bHasTexture;      // 是否具有纹理映射
  char strName[255];      // 对象的名称
  CVector3 *pVerts;      // 对象的顶点
  CVector3 *pNormals;    // 对象的法向量
  CVector2 *pTexVerts;    // 纹理UV坐标
  tFace *pFaces;        // 对象的面信息
};
// 模型信息结构体
struct t3DModel
{
  UINT texture[MAX_TEXTURES];
  int numOfObjects;          // 模型中对象的数目
  int numOfMaterials;          // 模型中材质的数目
  vector<tMaterialInfo> pMaterials;  // 材质链表信息
  vector<t3DObject> pObject;      // 模型中对象链表信息
};
      通过采用递归算法读取全部文件信息后,我们得到一个包含了我们下一步渲染所需要的全部信息的t3DObject结构体对象,具体读取实现这里不需要我赘述了吧,网上讲的太多了,呵呵 。
接着,我们开始建立顶点,以及索引缓冲区,以及材质区
D3DMATERIAL9*           g_pMeshMaterials = NULL; // Materials for our mesh
LPDIRECT3DTEXTURE9*     g_pMeshTextures  = NULL; // Textures for our mesh
DWORD                   g_dwNumMaterials = 0L;   // Number of mesh materials
LPDIRECT3DVERTEXBUFFER9
                        *g_pSubBuffer    =NULL;           //group for each sub
LPDIRECT3DINDEXBUFFER9  *g_pIndexBuffer  =NULL;
int*                     g_pNumVerts     =NULL;
int*                     g_pNumFaces     =NULL;

我们将使用循环依次读入每一个t3DObject结构体sub对象的子对象内容,tMaterialInfo pMaterials;  // 材质信息,t3DObject pObject;  // 模型中对象信息
具体实现可以参照我的源码,就是lock和unlock,呵呵。(对了,3ds。h往往读出的文件是适合GL右手系模型,而至少DX9及其以前都是左手系的,所以要注意顶点座标的转化),具体实现还是仁者见仁,方法不唯一。
最后,我们采用drawindexPrimative ,哈哈画出来了。

源码地址:
见附件

该原代码可能需要2006,8月前dx的sdk 才可编译运行,07的sdk据说有问题 还在处理中 有成功的希望回贴
exe运行 需要d3dx9_31.dll 没有的可以去网上下 很多的,然后放到systerm32 下 ,或者我的exe目录下即可

sf_20071022153413.rar

246.51 KB, 下载次数:

1

主题

3

帖子

0

积分

新手上路

Rank: 1

积分
0
 楼主| 发表于 2007-10-22 15:36:00 | 显示全部楼层

Re:用dx API 来渲染 3ds 模型文件(新手入门级)

虽然老调重谈,
呵呵 希望大家 多提建议

0

主题

14

帖子

14

积分

新手上路

Rank: 1

积分
14
发表于 2007-10-22 20:36:00 | 显示全部楼层

Re:用dx API 来渲染 3ds 模型文件(新手入门级)

还是喜欢用X文件多点,可以用conv3ds转换

0

主题

34

帖子

46

积分

注册会员

Rank: 2

积分
46
QQ
发表于 2007-10-22 21:18:00 | 显示全部楼层

Re:用dx API 来渲染 3ds 模型文件(新手入门级)

谢谢楼主了

0

主题

34

帖子

46

积分

注册会员

Rank: 2

积分
46
QQ
发表于 2007-10-22 21:26:00 | 显示全部楼层

Re:用dx API 来渲染 3ds 模型文件(新手入门级)

2006年12月的SDK,没做修改就可以运行
再次感谢楼主慷慨奉献
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-16 04:43

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表