DirectX简单的FBX文件加载(网格MESH)

DirectX简单的FBX文件加载(网格MESH)

FBX文件加载需要用到FBX SDK,有关配置可以自己上网或者查看官方文档进行设置(参见)
http://help.autodesk.com/view/FBX/2019/ENU/添加链接描述

这里只关注FBX文件中MESH的读取(也只是读取每个顶点的坐标而已,不进行坐标变换),十分的简单。由于FBX文件是按照节点组成的树形结构,所以这里的读取方法只能读取深度遍历下第一个mesh类型的节点。不过没有关系,可以用Blender把FBX文件的结构进行重塑(比如将mesh合并,调整左右手坐标系等),关键是原理。。。。

1.FBX初始化
先进行必要的FBX初始化然后导入
注意1:FBX不支持中文路径,Blender建模的时候节点命名也不要是中文,不然会乱码。
注意2:FBX网格基本图元有很多,四边形,三角形,五边形……,但是DirectX要三角形,所以要三角化。创建一个FbxGeometryConverter对象对整个场景进行三角化

FbxManager* m_pSdkManager;
FbxIOSettings* m_pios;
FbxImporter* m_pImporter;
m_pSdkManager=FbxManager::Create();	
m_pios=FbxIOSettings::Create(m_pSdkManager,IOSROOT);	
m_pSdkManager->SetIOSettings(m_pios);
m_pImporter=FbxImporter::Create(m_pSdkManager,"");
//开始导入我们需要加载的文件,这里的_filePath就是文件路径,注意FBX不支持中文路径
bool ImportStatus=m_pImporter->Initialize(_filePath,-1,m_pSdkManager->GetIOSettings());
if(!ImportStatus) return ImportStatus; 
//获得根节点
FbxScene* pScene=FbxScene::Create(m_pSdkManager,"myScene");
m_pImporter->Import(pScene);	
FbxNode* pRootNode=pScene->GetRootNode();
//三角化所有数据
FbxGeometryConverter converter(m_pSdkManager);
converter.Triangulate(pScene,true);
//遍历节点
ProcessNode(pRootNode);

2.ProcessNode
该函数实现了节点的遍历,传入根节点即可
FbxNodeAttribute::EType可以查看文档,发现除了FbxMesh我们需要其他暂时用不上
在这里插入图片描述

void FBX::ProcessNode(FbxNode* _pFbxNode){
	FbxNodeAttribute::EType attributeType;
	if(_pFbxNode->GetNodeAttribute()!=NULL){
		attributeType=_pFbxNode->GetNodeAttribute()->GetAttributeType();
		switch(attributeType){
		case FbxNodeAttribute::EType::eMesh:
			//处理网格数据
			ProcessMesh(_pFbxNode);
			break;
		}
	}
	for(int i=0;i<=_pFbxNode->GetChildCount()-1;++i)
		ProcessNode(_pFbxNode->GetChild(i));
}

3.ProcessMesh
要点1:从FbxMesh中获得顶点数组
要点2:从FbxVector4中得到我们需要的x,y,z
要点3:得到索引数组int ctrlPointIndex=pMesh->GetPolygonVertex(i,j)
这里的含义是从第i个三角形中获得第j个顶点的索引

void FBX::ProcessMesh(FbxNode* _pFbxNode){
	if(flag!=true) return; //这里的flag是当前是否遍历到过一个MESH,如果有就不遍历了,因为懒
	flag=false;//遍历过了,调整flag
	FbxMesh* pMesh=_pFbxNode->GetMesh();
	if(!pMesh) return;
	FBX_VERTEX* pVertexArray=NULL;//FBX_VERTEX是我定义的顶点格式,只有x,y,z坐标

	//顶点的存储
	int ctrlcount=pMesh->GetControlPointsCount();
	m_VertexCount=ctrlcount;//就是顶点个数
	pVertexArray=new FBX_VERTEX[ctrlcount];
	D3DXVECTOR3 vertex;
	FbxVector4* pCtrlPoint=pMesh->GetControlPoints();//这里的控制点数组pCtrlPoint其实就是DirectX里顶点的意思,就是顶点数组
	for(unsigned int i=0;i<=ctrlcount-1;i++){
		vertex.x=pCtrlPoint[i].mData[0];//这里得到控制点(顶点)的x,y,z
		vertex.y=pCtrlPoint[i].mData[1];//这段数据的获得找了好多资料才知道的
		vertex.z=pCtrlPoint[i].mData[2];//FBX的样例真心看不懂
		//接下来存入我们的顶点数组中
		pVertexArray[i]=FBX_VERTEX(vertex);
	}
	//创建顶点缓存
	HRESULT hr=m_pd3dDevice->CreateVertexBuffer(
	ctrlcount*sizeof(FBX_VERTEX),0,FVF,D3DPOOL_MANAGED,&m_pVertexBuffer,0);
	if(FAILED(hr)) exit(1);
	//存入顶点缓存中
	FBX_VERTEX* lVertexArray;
	m_pVertexBuffer->Lock(0,0,(void**)&lVertexArray,0);
	memcpy(lVertexArray,pVertexArray,ctrlcount*sizeof(FBX_VERTEX));
	m_pVertexBuffer->Unlock();
	delete [] pVertexArray;

	//索引的存储,故技重施即可,但有一点需要注意
	int* pIndexArray=NULL;
	unsigned int triangleCount=pMesh->GetPolygonCount();//多边形图元的数量
	//因为已经三角化过,所以一定是三角形了
	m_TriangleCount=triangleCount;//三角形面片的数量
	pIndexArray=new int[triangleCount*3];//三角形面皮的数量*3就是索引的数量
	unsigned int index_count=0;
	for(unsigned int i=0;i<=triangleCount-1;i++){
		//这里一定是三角形了也可判断下
		/*
		if(pMesh->GetPolygonSize(i)!=3){return;}
		*/
		for(unsigned int j=0;j<=pMesh->GetPolygonSize(i)-1;j++){
			int ctrlPointIndex=pMesh->GetPolygonVertex(i,j);
			//这里要存入索引数组中
			pIndexArray[index_count]=ctrlPointIndex;
			index_count++;
		}
	}
	//创建索引数组
	hr=m_pd3dDevice->CreateIndexBuffer(
	(index_count+1)*sizeof(int),0,D3DFMT_INDEX32,D3DPOOL_MANAGED,&m_pIndexBuffer,0);
	if(FAILED(hr)) exit(1);
	
	int* lIndexArray;
	m_pIndexBuffer->Lock(0,0,(void**)&lIndexArray,0);
	memcpy(lIndexArray,pIndexArray,(index_count+1)*sizeof(int));
	m_pIndexBuffer->Unlock();
	delete [] pIndexArray;
	
}

4.Draw
开始绘制

void FBX::Draw(D3DXMATRIX _mat)
{
	//_mat暂时不知道干什么,但是有用,可以以后指定模型的位置
	//m_pd3dDevice->BeginScene();
	m_pd3dDevice->SetStreamSource(0,m_pVertexBuffer,0,sizeof(FBX_VERTEX));
	m_pd3dDevice->SetIndices(m_pIndexBuffer);
	m_pd3dDevice->SetFVF(FVF);
	m_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,m_VertexCount,0,m_TriangleCount);
	//m_pd3dDevice->EndScene();
}

这里只展示了部分代码,我将这些东西写了一个FBX类,用来导入FBX文件
实验怎么导入FBX网格文件,以龙书的Camera例程为主体,可以遨游观看FBX文件
效果图:
1.FBX SDK中的humanoid.fbx,这里倒了是因为这个fbx用右手坐标系,而DirectX用左手。因为可以用Blender调整这里也不管了。话说为什么高考数学要用右手坐标系做立体几何???DirectX习惯了表示只会左手坐标系,到头来答案错了一分莫得。。。。
在这里插入图片描述
2.自己用Blender做的一个简单模型(还带有动画,等以后解析完了FBX的动画在看看)
在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: Qt3D是一个用于创建3D应用程序的Qt模块,支持加载和展示各种3D模型格式,包括FBX模型。 要加载FBX模型,首先需要在Qt项目中引入Qt3D模块,并在代码中创建一个Qt3D场景和一个Qt3D实体(Entity)。然后,可以通过Qt3D提供的加载器(如QSceneLoader)来加载FBX模型文件加载FBX模型的步骤如下: 1. 创建一个Qt3D场景和一个实体: Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity(); Qt3DRender::QCamera *cameraEntity = view.camera(); 2. 创建一个Qt3D加载器,并设置加载器的模型文件路径: Qt3DRender::QSceneLoader *loader = new Qt3DRender::QSceneLoader(); loader->setSource(QUrl::fromLocalFile("path/to/your/fbx/file.fbx")); 3. 将加载器添加到实体中: rootEntity->addComponent(loader); 4. 将根实体添加到场景中,并将相机与场景关联: Qt3DExtras::Qt3DWindow view; view.setRootEntity(rootEntity); view.show(); 以上步骤将加载并展示FBX模型。你可以通过进一步的Qt3D组件和功能来实现模型的自定义渲染、动画控制和交互等。 需要注意的是,FBX是一种二进制文件格式,需要先将其转换为Qt3D可读取的格式。可以使用FBX SDK或其他相关工具来进行模型转换和预处理。 总结,通过引入Qt3D模块和使用Qt3D加载器,我们可以在Qt应用程序中加载和展示FBX模型。灵活的Qt3D框架还提供了许多功能来处理和渲染3D模型,使我们能够在应用程序中创建丰富的3D体验。 ### 回答2: Qt3D 是一个用于创建3D图形应用程序的Qt模块。它支持加载多种3D模型格式,其中包括FBXFBX是一种广泛使用的3D模型格式,由Autodesk开发并支持。 要加载一个FBX模型,我们需要进行以下步骤: 1. 首先,我们需要在我们的Qt应用程序中包含Qt3D模块。在.pro文件中添加如下行: ``` QT += 3dcore 3drender 3dinput ``` 2. 然后,我们需要创建一个Qt3D渲染窗口来显示我们的3D场景。我们可以使用QQuickView或QWindow派生的自定义窗口,具体使用哪个取决于我们的应用程序需求。 3. 接下来,我们需要创建一个QEntity对象作为场景的根节点。这个对象可以包含其他实体和组件。 4. 然后,我们可以使用QSceneLoader组件来加载FBX模型文件。我们需要将这个组件添加到场景中,并指定FBX文件的路径。 ```cpp QSceneLoader *sceneLoader = new QSceneLoader(); sceneLoader->setSource(QUrl::fromLocalFile("path/to/fbx/file.fbx")); QEntity *modelEntity = new QEntity(); modelEntity->addComponent(sceneLoader); ``` 5. 最后,我们可以将模型实体添加到场景的根节点中,并在渲染窗口中显示场景。 ```cpp rootEntity->addEntity(modelEntity); view->setRootEntity(rootEntity); view->show(); ``` 这样,我们就成功加载FBX模型并在Qt3D应用程序中显示出来了。我们可以通过添加其他组件和实体来对模型进行进一步的修改和控制。 在加载FBX模型之前,我们需要确保我们的应用程序已经安装了Qt3D模块。可以使用Qt的在线安装程序或源码编译安装Qt以获取Qt3D模块。 以上是一个简单的示例,演示了如何使用Qt3D加载FBX模型。根据我们的需求,我们可以在加载模型之后进行更多高级操作和修改。 ### 回答3: Qt3D是Qt框架中的一个模块,用于实现3D图形的渲染和交互。而FBX是一种用于存储和传输3D模型和动画数据的文件格式。 要在Qt3D中加载并显示FBX模型,首先需要导入Qt3D相关的头文件,并创建一个Qt3D的场景。 然后,需要创建一个Qt3D中的实体(Entity)来表示我们要加载FBX模型。可以使用Qt3D提供的QEntity类来创建实体,并将其添加到场景中。 接下来,需要创建一个Qt3D中的组件(Component),将FBX模型加载到实体中。Qt3D提供了QSceneLoader组件,可以用来加载FBX模型文件。通过调用QSceneLoader的setSource函数,可以指定要加载FBX文件路径。然后,将该组件添加到实体中。 最后,将实体添加到场景中,并启动Qt3D的渲染循环,即可在窗口中显示加载FBX模型。 除了加载FBX模型,Qt3D还提供了许多其他功能,如光照、材质、相机等,可以通过设置相应的组件和属性来实现。在加载后,可以通过操作相应的组件来对模型进行旋转、平移、缩放等操作,实现交互效果。 需要注意的是,加载FBX模型时需要保证FBX文件的路径正确,并且需要安装对应的FBX导入插件,以便Qt3D能够正常解析和加载FBX文件

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值