在Direct3D9中,怎样加载Mesh模型?

tianxiangyuan 2004-07-27 02:13:12
我刚接触Direct3D9,只了解到 可以使用D3DXLoadMeshFromX()函数加载.x文件描述的模型。如果不使用该函数,该怎么办?最好给出例子,并详细的解释。请不吝赐教,定重分酬谢!
...全文
273 11 打赏 收藏 举报
写回复
11 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
kofightas 2004-08-05
楼上说得非常之好,想用.x格式的mesh, 就用d3d现成的函数。
如果你想用自己的格式或者3dmax的格式什么的,自己写函数吧。
  • 打赏
  • 举报
回复
寻开心 2004-08-03
不用D3DXLoadMeshFromFile或者D3DXLoadMeshFromFileEx这样的函数就无法和MESH的使用方法保持一致

主要不在于别的,而仅仅在于D3D资源管理功能上
D3D可以根据当前系统资源紧张状态,自动从内存当中按照一定的机制卸载不常用的资源,装载需要的资源,来完成显示内存不足的情况下的处理机制

其他的东西,都可以自己写语法分析器来实现,也就是根据.x文件的格式描述,自己写一个加载函数。但是加载到内存当中的VertexBuffer,IndexBuffer,Texture等东西很难再和D3D自己的资源管理挂钩了。只能自己来管理,根据显存状态判定那些加载到显存,那些保留在内存当中。

DXSDK当中的例子,用到模型的除了用mesh函数自己创建的盒子,球之类的以外,都是用前面说的那两个函数来加载的。
.x文件和其他格式文件相比,只有在D3D内部所封装的那些管理机制,加载处理函数上有优势,因为本来它就是DX为了方便它自己使用而提出的和DX的内存格式相对应的一个格式。其他没有特别的,尤其是不支持多重贴图的特性让人无法忍受。
  • 打赏
  • 举报
回复
mynetpc 2004-07-31
到msdn下个例子看看就可以了
  • 打赏
  • 举报
回复
littlepig_2002 2004-07-30
用3DS之类的建模软件制作的模型. 需要写导出插件, 将各种数据写到文件中.
X文件是微软件的导出插件导出的格式, 使用方便.
如果要使用自己的格式, 就要学习如何写建模软件的导出插件. 当然资料是非常
有限的.
看你想研究什么了? 如果你想研究插件, 也需要很长时间. 如果你想研究其它的方面,
比如地形, 室内, 光照之类的, 你就没有时间研究导出插件了. 还不如将X文件转换成
自己的格式. 对于X文件, DX不是有一些函数, 可以利用之得到几何数据, 纹理, 光照
数据等必须的数据, 然后按自己的格式写到文件中.
不管哪个方面, 都需要很长时间研究. 所以深入自己想研究的方面, 其它的等有时间了
再研究吧.
  • 打赏
  • 举报
回复
楼上的~,敬仰的kanepeng.
呵呵,虽然俺也挂四个绿叉子。
但是俺们的水平跟你差太多了。呵呵。
不是我们不知道用自已的格式。
只是还没研究透。呵呵~
  • 打赏
  • 举报
回复
bopengbopeng 2004-07-27
呵呵,楼主要的是不用D3DXLoadMeshFromX的方法,楼上的都用了。

但是我觉得很奇怪,为什么不用现成的呢?还不如干脆不用.x而用自己的格式。
  • 打赏
  • 举报
回复
nonocast 2004-07-27
Loading a .x file into your program (在程序中载入.x文件)
这一章我们会增加一个新的类CMesh,它的功能是渲染从.x文件中读取的网格(Mesh)。下面有CMesh类的源代码,它的构造函数将展示出怎样从.x文件中读取网格(Mesh)并且将它们保存至内存,它的析构函数将展示出怎样释放网格所占有的内存。它的渲染模块会告诉你怎样渲染网格(Mesh)。

CMesh类的构造函数有两个输入参数:第一个是DX设备,我们早就接触过了;第二个是要读取的.x文件的文件名,这个很好理解。我们用D3DXLoadMeshFromX函数来完成把网格载入内存的工作。然后,我们会创建两个数组,分别用于保存模型的材质和纹理。然后我们会有一个循环,其实它的功能就是从文件(由.x文件给定)中读取纹理并保存到数组中。最后,我们克隆了网格并且调用了D3DXComputeNormals函数来设置法线。
(译者:其实原著这里说的也不是很详细,不明白就研究源代码吧)

在析构函数中我们释放了网格和纹理占用的内存,还有前面创建的两个数组,都通通释放了。

渲染模块是很简单的,我们会循环的处理网格的每个子集,并且用适当的纹理和材质渲染它们。

CMesh::CMesh(LPDIRECT3DDEVICE8 pD3DDevice, LPSTR pFilename)
{
LPD3DXBUFFER pMaterialsBuffer = NULL;
LPD3DXMESH pMesh = NULL;

m_pD3DDevice = pD3DDevice;

if(FAILED(D3DXLoadMeshFromX(pFilename, D3DXMESH_SYSTEMMEM, m_pD3DDevice, NULL,
&pMaterialsBuffer, &m_dwNumMaterials, &pMesh)))
{
m_pMesh = NULL;
m_pMeshMaterials = NULL;
m_pMeshTextures = NULL;

LogError("<li>Mesh '%s' failed to load", pFilename);
return;
}

D3DXMATERIAL* matMaterials = (D3DXMATERIAL*)pMaterialsBuffer->GetBufferPointer();

//Create two arrays. One to hold the materials and only to hold the textures
m_pMeshMaterials = new D3DMATERIAL8[m_dwNumMaterials];
m_pMeshTextures = new LPDIRECT3DTEXTURE8[m_dwNumMaterials];

for(DWORD i = 0; i < m_dwNumMaterials; i++)
{
//Copy the material
m_pMeshMaterials[i] = matMaterials[i].MatD3D;

//Set the ambient color for the material (D3DX does not do this)
m_pMeshMaterials[i].Ambient = m_pMeshMaterials[i].Diffuse;

//Create the texture
if(FAILED(D3DXCreateTextureFromFile(m_pD3DDevice,
matMaterials[i].pTextureFilename,
&m_pMeshTextures[i])))
{
m_pMeshTextures[i] = NULL;
}
}

//We've finished with the material buffer, so release it
SafeRelease(pMaterialsBuffer);


//Make sure that the normals are setup for our mesh
pMesh->CloneMeshFVF(D3DXMESH_MANAGED, MESH_D3DFVF_CUSTOMVERTEX,
m_pD3DDevice, &m_pMesh);
SafeRelease(pMesh);

D3DXComputeNormals(m_pMesh);


LogInfo("<li>Mesh '%s' loaded OK", pFilename);
}

CMesh::~CMesh()
{
SafeDelete(m_pMeshMaterials);

if(m_pMeshTextures != NULL)
{
for(DWORD i = 0; i < m_dwNumMaterials; i++)
{
if(m_pMeshTextures[i])
{
SafeRelease(m_pMeshTextures[i]);
}
}
}

SafeDelete(m_pMeshTextures);
SafeRelease(m_pMesh);

LogInfo("<li>Mesh destroyed OK");
}

DWORD CMesh::Render()
{
if(m_pMesh != NULL)
{
for(DWORD i = 0; i < m_dwNumMaterials; i++)
{
m_pD3DDevice->SetMaterial(&m_pMeshMaterials[i]);
m_pD3DDevice->SetTexture(0, m_pMeshTextures[i]);

m_pMesh->DrawSubset(i);
}

return m_pMesh->GetNumFaces();
}
else
{
return 0;
}
}

Scaling makes your object darker? (缩放使你的对象变暗了?)
还有一点需要注意的是,如果你缩放了网格,同时你也缩放了法线。这可能会使你的对象看起来发暗,解决的办法是激活D3DRS_NORMALIZENORMALS渲染状态:

m_pD3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE);


// Andy Pike的教程中的
你要完整的话,可以到google里面搜索一下,肯定有下载的

may you succeed!
  • 打赏
  • 举报
回复
nonocast 2004-07-27
// Mesh.cpp: implementation of the CMesh class.
//
//////////////////////////////////////////////////////////////////////

#include "Mesh.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CMesh::CMesh(LPDIRECT3DDEVICE8 pD3DDevice, LPSTR pFilename)
{
LPD3DXBUFFER pMaterialsBuffer = NULL;
LPD3DXMESH pMesh = NULL;

m_pD3DDevice = pD3DDevice;

if(FAILED(D3DXLoadMeshFromX(pFilename, D3DXMESH_SYSTEMMEM, m_pD3DDevice, NULL,
&pMaterialsBuffer, &m_dwNumMaterials, &pMesh)))
{
m_pMesh = NULL;
m_pMeshMaterials = NULL;
m_pMeshTextures = NULL;

LogError("<li>Mesh '%s' failed to load", pFilename);
return;
}

D3DXMATERIAL* matMaterials = (D3DXMATERIAL*)pMaterialsBuffer->GetBufferPointer();

//Create two arrays. One to hold the materials and only to hold the textures
m_pMeshMaterials = new D3DMATERIAL8[m_dwNumMaterials];
m_pMeshTextures = new LPDIRECT3DTEXTURE8[m_dwNumMaterials];

for(DWORD i = 0; i < m_dwNumMaterials; i++)
{
// Copy the material
m_pMeshMaterials[i] = matMaterials[i].MatD3D;

// Set the ambient color for the material (D3DX does not do this)
m_pMeshMaterials[i].Ambient = m_pMeshMaterials[i].Diffuse;

// Create the texture
if(FAILED(D3DXCreateTextureFromFile(m_pD3DDevice,
matMaterials[i].pTextureFilename,
&m_pMeshTextures[i])))
{
m_pMeshTextures[i] = NULL;
}
}

//We've finished with the material buffer, so release it
SafeRelease(pMaterialsBuffer);


//Make sure that the normals are setup for our mesh
pMesh->CloneMeshFVF(D3DXMESH_MANAGED, MESH_D3DFVF_CUSTOMVERTEX, m_pD3DDevice, &m_pMesh);
SafeRelease(pMesh);

D3DXComputeNormals(m_pMesh);


LogInfo("<li>Mesh '%s' loaded OK", pFilename);
}

CMesh::~CMesh()
{
SafeDelete(m_pMeshMaterials);

if(m_pMeshTextures != NULL)
{
for(DWORD i = 0; i < m_dwNumMaterials; i++)
{
if(m_pMeshTextures[i])
{
SafeRelease(m_pMeshTextures[i]);
}
}
}

SafeDelete(m_pMeshTextures);
SafeRelease(m_pMesh);

LogInfo("<li>Mesh destroyed OK");
}

DWORD CMesh::Render()
{
if(m_pMesh != NULL)
{
for(DWORD i = 0; i < m_dwNumMaterials; i++)
{
m_pD3DDevice->SetMaterial(&m_pMeshMaterials[i]);
m_pD3DDevice->SetTexture(0, m_pMeshTextures[i]);

m_pMesh->DrawSubset(i);
}

return m_pMesh->GetNumFaces();
}
else
{
return 0;
}
}
  • 打赏
  • 举报
回复
nonocast 2004-07-27
// Mesh.h: interface for the CMesh class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_MESH_H__F87899E4_6F53_4769_B9C3_2ED555BC3871__INCLUDED_)
#define AFX_MESH_H__F87899E4_6F53_4769_B9C3_2ED555BC3871__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "Base.h"

#define MESH_D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1)

class CMesh : public CBase
{
public:
DWORD Render();
CMesh(LPDIRECT3DDEVICE8 pD3DDevice, LPSTR pFilename);
virtual ~CMesh();

private:
LPDIRECT3DDEVICE8 m_pD3DDevice;
DWORD m_dwNumMaterials;
LPD3DXMESH m_pMesh;
D3DMATERIAL8* m_pMeshMaterials;
LPDIRECT3DTEXTURE8* m_pMeshTextures;
};

#endif // !defined(AFX_MESH_H__F87899E4_6F53_4769_B9C3_2ED555BC3871__INCLUDED_)
  • 打赏
  • 举报
回复
sorry.~,呵呵,其它的方法我也不会。~
  • 打赏
  • 举报
回复
收到短信:
请参看:
http://www.gdiy.com/main1.asp
前两个下载包
  • 打赏
  • 举报
回复
发帖
游戏开发

8161

社区成员

游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
帖子事件
创建了帖子
2004-07-27 02:13
社区公告
暂无公告