Advertisement Jump to content
Sign in to follow this  
Saad Manzur

Directx 11 File Importing

This topic is 1800 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,
I'm pretty new in game developing. I've been working with directx for the past few months now. I cannot import 3d file in directx 11. Everyone is suggesting either Assimp or fbxsdk. But I cannot find any good tutorial online with directx. I tried fbxsdk and managed to create a vertex buffer. But when I try to draw nothing happens no error just nothing . I dont understand what is happening here . Am I doing it wrong ?? Here is my fbx loader code ... Please help me...

 

void CameraApp::BuildFbx()
{
	int numVertices;
	FbxManager *pFbxSdkManager = NULL;

	pFbxSdkManager = FbxManager::Create();

	FbxIOSettings *pIOSettings = FbxIOSettings::Create(pFbxSdkManager,IOSROOT);
	pFbxSdkManager->SetIOSettings(pIOSettings);

	FbxImporter *pImporter = FbxImporter::Create(pFbxSdkManager, "");
	bool result = pImporter->Initialize("human_new.fbx", -1, pFbxSdkManager->GetIOSettings());

	FbxScene *pScene = FbxScene::Create(pFbxSdkManager,"tempScene");

	pImporter->Import(pScene);
	pImporter->Destroy();

	FbxNode *pRootNode = pScene->GetRootNode();

	int numChildren = pRootNode->GetChildCount();

	out_file << "Number of children : " << numChildren << "\n";

	FbxNode *childNode = 0;

	std::vector<Vertex::Basic32> vertices;

	for (int i = 0; i < numChildren; i++)
	{
		childNode = pRootNode->GetChild(i);
		out_file << "Child Name : " << childNode->GetName() << "\n";
		FbxMesh *pMesh = (FbxMesh *)childNode->GetNodeAttribute();
		if (!pMesh)
		{
			out_file << "No mesh\n";
		}
		else
		{
			out_file << "Loading mesh\n";

			out_file << "Polygon Count : " << pMesh->GetPolygonCount() << "\n";

			FbxVector4 *pVertices = pMesh->GetControlPoints();
			FbxVector4 normal;

			vertices.resize(pMesh->GetPolygonCount() * 3);

			for (int j = 0; j < pMesh->GetPolygonCount(); j++)
			{
				numVertices = pMesh->GetPolygonSize(j);

				for (int k = 0; k < numVertices; k++)
				{
					int iControlIndex = pMesh->GetPolygonVertex(j, k);
					/*out_file << "\n";
					out_file << pVertices[iControlIndex].mData[0] << " " << pVertices[iControlIndex].mData[1] << " " << pVertices[iControlIndex].mData[2];*/
					vertices[j * 3 + k].Pos.x = pVertices[iControlIndex].mData[0];
					vertices[j * 3 + k].Pos.y = pVertices[iControlIndex].mData[1];
					vertices[j * 3 + k].Pos.z = pVertices[iControlIndex].mData[2] * (-1.0f);

					/*out_file << "\n";
					out_file << vertices[j * 3 + k].Pos.x << " " << vertices[j * 3 + k].Pos.y << " " << vertices[j * 3 + k].Pos.z;*/
				}

				out_file << "\n\n\n";

				for (int k = 0; k < numVertices; k++)
				{
					pMesh->GetPolygonVertexNormal(j, k, normal);
					out_file << normal.mData[0] << " " << normal.mData[1] << " " << normal.mData[2] << "\n";

					vertices[j * 3 + k].Normal.x = normal.mData[0];
					vertices[j * 3 + k].Normal.y = normal.mData[1];
					vertices[j * 3 + k].Normal.z = normal.mData[2] *(-1.0f);
				}
				
			}
		}
	}

	pRootNode->Destroy();
	pScene->Destroy();

	D3D11_BUFFER_DESC vbd;
	vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	vbd.Usage = D3D11_USAGE_IMMUTABLE;
	vbd.ByteWidth = sizeof(Vertex::Basic32)*numVertices;
	vbd.CPUAccessFlags = 0;
	vbd.MiscFlags = 0;

	D3D11_SUBRESOURCE_DATA vinitData;
	vinitData.pSysMem = &vertices[0];
	HR(md3dDevice->CreateBuffer(&vbd, &vinitData, &mFbxVB));

	mFbxVertexCount = vertices.size();
}

and My render function calls this ..
 

activeFbxTech->GetDesc(&techDesc);
	for (UINT p = 0; p < techDesc.Passes; p++)
	{
		md3dImmediateContext->IASetVertexBuffers(0, 1, &mFbxVB, &stride, &offset);

		XMMATRIX world = XMLoadFloat4x4(&mFbxWorld);
		XMMATRIX worldInvTranspose = MathHelper::InverseTranspose(world);
		XMMATRIX worldViewProj = world*view*proj;

		Effects::BasicFX->SetWorld(world);
		Effects::BasicFX->SetWorldInvTranspose(worldInvTranspose);
		Effects::BasicFX->SetWorldViewProj(worldViewProj);
		Effects::BasicFX->SetMaterial(mFbxMat);

		activeFbxTech->GetPassByIndex(p)->Apply(0, md3dImmediateContext);
		md3dImmediateContext->Draw(mFbxVertexCount,0);
	}

What am I doing wrong ??

 

Share this post


Link to post
Share on other sites
Advertisement

When trying to find errors, make sure that you create your D3D11 device as a debug device:

http://msdn.microsoft.com/en-us/library/windows/desktop/jj200584(v=vs.85).aspx

 

 

If you're using VS2013, then get to know the visual studio graphics debugger:

http://msdn.microsoft.com/en-us/library/hh315751.aspx

http://blogs.msdn.com/b/vcblog/archive/2011/11/08/10235150.aspx

 

Otherwise, get to know PIX:

http://mynameismjp.wordpress.com/2010/02/14/d3d-performance-and-debugging-tools-round-up-pix/

http://tomtech999.wordpress.com/2011/09/07/debugging-directx-applications-with-pix-for-windows/

 

These tools will let you see the state of the device at any time, and to see how vertices and pixels are being processed.

 

 

I only had a quick look at your code, but instead of

vbd.ByteWidth = sizeof(Vertex::Basic32)*numVertices // num verts found in the last mesh
you probably want:
vbd.ByteWidth = sizeof(Vertex::Basic32)*vertices.size() // num verts total

Share this post


Link to post
Share on other sites

My directx 11 model loader using assimp

#include "stdafx.h"
 
//================== .h file ===============================

#ifndef _MODEL_H_
#define _MODEL_H_
 
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
 
 
class MeshGeometry
{
public:
struct Subset
{
Subset()
{
ID = -1;
 
VertexCount = 0;
FaceCount = 0;
 
VertexStart = 0;
FaceStart = 0;
}
 
UINT ID;
UINT VertexStart;
UINT VertexCount;
UINT FaceStart;
UINT FaceCount;
 
};
 
public:
MeshGeometry();
~MeshGeometry();
 
template <typename VertexType>
void SetVertices(const VertexType* vertices, UINT count);
void SetIndices(const USHORT* indices, UINT count);
void SetSubsetTable(std::vector<Subset>& subsetTable);
 
void Draw(UINT subsetID);
 
private:
MeshGeometry(const MeshGeometry& rhs);
MeshGeometry& operator=(const MeshGeometry& rhs);
 
private:
ID3D11Buffer* VertexBuffer;
ID3D11Buffer* IndexBuffer;
 
DXGI_FORMAT IndexBufferFormat;
UINT VertexStride;
 
std::vector<Subset> SubsetTable;
};
 
 
 
class Model16
{
public:
struct InitInfo
{
//pointer to texture manager so that a same texture
//doesn't get loaded multiple times
TextureMgr* Mgr;
 
//Optional
//only set this if you want to manually set material
Material Material; 
 
//Set this to 0 for no lights
//NOTE: the number cannot be greater than 3
USHORT NumLights; 
 
//set this to true if you want to use materials loaded from model
//else set this to false if you want to manually specify materials
bool UseDefaultMaterial; 
};
 
std::vector<Vertex::Basic32> vertices;
public:
Model16();
~Model16();
 
void LoadModel(const std::string& FileName);
void Render(CXMMATRIX World);
 
void SetDirLight01(DirectionalLight& DirLight1);
void SetDirLight02(DirectionalLight& DirLight2);
void SetDirLight03(DirectionalLight& DirLight3);
 
void SetInitInfo(InitInfo& info);
private:
struct ModelData
{ 
ModelData()
{
mNumVertices = 0;
mNumFaces = 0;
mSubsetCount = 0;
}
 
MeshGeometry Mesh;
 
UINT mNumVertices;
UINT mNumFaces;
UINT mSubsetCount;
 
};
 
DirectionalLight Lights[3];
 
 
std::vector<ID3D11ShaderResourceView*> DiffuseMapSRV;
std::vector<Material> Materials;
 
ModelData mModel;
InitInfo mInfo;
};
 
 
 
#endif

 
 
//================== .cpp file ===========================
Model16::Model16()
{
//by default there are 3 directional lights
//but sometimes we don't want to compute lighting calculation for some objects
//which would go almost unnoticed so this class provides abilities for setting lights
//if the user sets 0 lights in initinfo then there would be no lighting calculation done 
 
//Init default light source
 
//50% light from front
Lights[0].Ambient  = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
Lights[0].Diffuse  = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
Lights[0].Specular = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
Lights[0].Direction = XMFLOAT3(0.707f, -0.707f, 0.0f);
 
//45% light from back
Lights[1].Ambient  = XMFLOAT4(0.45f, 0.45f, 0.45f, 1.0f);
Lights[1].Diffuse  = XMFLOAT4(0.45f, 0.45f, 0.45f, 1.0f);
Lights[1].Specular = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
Lights[1].Direction = XMFLOAT3(-0.707f, 0.707f, 0.0f);
 
 
//35% light from front
Lights[2].Ambient  = XMFLOAT4(0.35f, 0.35f, 0.35f, 1.0f);
Lights[2].Diffuse  = XMFLOAT4(0.35f, 0.35f, 0.35f, 1.0f);
Lights[2].Specular = XMFLOAT4(0.25f, 0.25f, 0.25f, 1.0f);
Lights[2].Direction = XMFLOAT3(0.707f, -0.707f, 0.0f);
 
 
mInfo.Mgr = nullptr;
mInfo.NumLights = 3;
mInfo.UseDefaultMaterial = true;
}
 
Model16::~Model16()
{
 
}
 
 
 
void Model16::LoadModel(const std::string& filename)
{
 
Assimp::Importer imp;
 
const aiScene* pScene = imp.ReadFile(filename,
   aiProcess_CalcTangentSpace |
aiProcess_JoinIdenticalVertices |
        aiProcess_Triangulate |
        aiProcess_GenSmoothNormals |
aiProcess_OptimizeMeshes |
aiProcess_PreTransformVertices |
aiProcess_RemoveRedundantMaterials |
        aiProcess_ConvertToLeftHanded |
        aiProcess_SortByPType);
 
if (pScene == NULL)
ShowError(imp.GetErrorString());
 
 
std::vector<USHORT> indices;
 
std::vector<MeshGeometry::Subset> subsets;
 
 
for (UINT i = 0; i < pScene->mNumMeshes; i++)
{
aiMesh* mesh = pScene->mMeshes[i];
 
MeshGeometry::Subset subset;
 
subset.VertexCount = mesh->mNumVertices;
subset.VertexStart = vertices.size();
subset.FaceStart = indices.size() / 3;
subset.FaceCount = mesh->mNumFaces;
subset.ID = mesh->mMaterialIndex;
 
mModel.mNumFaces += mesh->mNumFaces;
mModel.mNumVertices += mesh->mNumVertices;
 
for (UINT j = 0; j < subset.VertexCount; j++)
{
Vertex::Basic32 vertex;
 
vertex.Pos.x = mesh->mVertices[j].x;
vertex.Pos.y = mesh->mVertices[j].y;
vertex.Pos.z = mesh->mVertices[j].z;
 
vertex.Normal.x = mesh->mNormals[j].x;
vertex.Normal.y = mesh->mNormals[j].y;
vertex.Normal.z = mesh->mNormals[j].z;
 
if (mesh->HasTextureCoords(0))
{
  vertex.Tex.x = mesh->mTextureCoords[0][j].x;
  vertex.Tex.y =  mesh->mTextureCoords[0][j].y;
}
 
vertices.push_back(vertex);
}
 
for (UINT j = 0; j < subset.FaceCount; j++)
{
for (UINT index = 0; index < mesh->mFaces[j].mNumIndices; index++)
{
indices.push_back(subset.VertexStart + mesh->mFaces[j].mIndices[index]);
}
}
 
 
 
 
aiMaterial* Mat = pScene->mMaterials[subset.ID];
 
if (mInfo.UseDefaultMaterial)
{ 
Material tempMat;
 
   aiColor4D color(0.0f, 0.0f, 0.0f, 0.0f);
 
   tempMat.Ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 0.0f);
   tempMat.Diffuse = XMFLOAT4(0.0f, 0.0f, 0.0f, 0.0f);
   tempMat.Specular = XMFLOAT4(0.0f, 0.0f, 0.0f, 0.0f);
   tempMat.Reflect = XMFLOAT4(0.0f, 0.0f, 0.0f, 0.0f);
 
   Mat->Get(AI_MATKEY_COLOR_AMBIENT, color);
 
   tempMat.Ambient = XMFLOAT4(color.r, color.g, color.b, color.a);
 
   Mat->Get(AI_MATKEY_COLOR_DIFFUSE, color);
 
   tempMat.Diffuse = XMFLOAT4(color.r, color.g, color.b, color.a);
 
   Mat->Get(AI_MATKEY_COLOR_SPECULAR, color);
 
   tempMat.Specular = XMFLOAT4(color.r, color.g, color.b, color.a);
 
   Mat->Get(AI_MATKEY_COLOR_REFLECTIVE, color);
 
   tempMat.Reflect = XMFLOAT4(color.r, color.g, color.b, color.a);
 
  //set material if there is no material
  if (tempMat.Ambient.x == 0 && tempMat.Ambient.y == 0 && tempMat.Ambient.z == 0 && tempMat.Ambient.w == 0)
  tempMat.Ambient = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
 
  if (tempMat.Diffuse.x == 0 && tempMat.Diffuse.y == 0 && tempMat.Diffuse.z == 0 && tempMat.Diffuse.w == 0)
  tempMat.Diffuse = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);
 
  if (tempMat.Specular.x == 0 && tempMat.Specular.y == 0 && tempMat.Specular.z == 0 && tempMat.Specular.w == 0)
  tempMat.Specular = XMFLOAT4(0.6f, 0.6f, 0.6f, 16.0f);
 
  Materials.push_back(tempMat);
}
else
{
Materials.push_back(mInfo.Material);
}
 
aiString path;
 
if (Mat->GetTextureCount(aiTextureType_DIFFUSE) > 0 && Mat->GetTexture(aiTextureType_DIFFUSE, 0, &path) == AI_SUCCESS)
{
char cpath[75];
 
sprintf(cpath, "Resources\\Textures\\%s", path.C_Str());
 
ID3D11ShaderResourceView* srv = mInfo.Mgr->CreateTexture(cpath);
 
DiffuseMapSRV.push_back(srv);
}
 
subsets.push_back(subset);
}
 
mModel.mSubsetCount = subsets.size();
 
mModel.Mesh.SetSubsetTable(subsets);
mModel.Mesh.SetIndices(&indices[0], indices.size());
mModel.Mesh.SetVertices(&vertices[0], vertices.size());
 
 
}
 
 
void Model16::SetDirLight01(DirectionalLight& Light)
{
Lights[0] = Light;
}
 
void Model16::SetDirLight02(DirectionalLight& Light)
{
Lights[1] = Light;
}
 
void Model16::SetDirLight03(DirectionalLight& Light)
{
Lights[2] = Light;
}
 
void Model16::SetInitInfo(InitInfo& info)
{
mInfo = info;
}
 
void Model16::Render(CXMMATRIX World)
{
 
ID3DX11EffectTechnique* activeTech;
 
 
    XMMATRIX worldInvTranspose = MathHelper::InverseTranspose(World);
XMMATRIX worldViewProj = World * d3d->m_Cam.ViewProj();
 
pDeviceContext->IASetInputLayout(InputLayouts::Basic32);
 
Effects::BasicFX->SetDirLights(Lights);
Effects::BasicFX->SetEyePosW(d3d->m_Cam.GetPosition());
 
if (mInfo.NumLights == 1)
activeTech = Effects::BasicFX->Light1TexAlphaClipTech;
else if (mInfo.NumLights == 2)
   activeTech = Effects::BasicFX->Light2TexAlphaClipTech;
else if (mInfo.NumLights == 3)
activeTech = Effects::BasicFX->Light3TexAlphaClipTech;
else if (mInfo.NumLights == 0)
activeTech = Effects::BasicFX->Light0TexAlphaClipTech;
 
 
Effects::BasicFX->SetWorld(World);
Effects::BasicFX->SetWorldInvTranspose(worldInvTranspose);
Effects::BasicFX->SetWorldViewProj(worldViewProj);
Effects::BasicFX->SetTexTransform(XMMatrixIdentity());
 
 
D3DX11_TECHNIQUE_DESC techDesc;
    activeTech->GetDesc(&techDesc);
 
pDeviceContext->RSSetState(0);
 
    for(UINT p = 0; p < techDesc.Passes; ++p)
    {
for (UINT i = 0; i < mModel.mSubsetCount; i++)
   {   
 
   Effects::BasicFX->SetMaterial(Materials[i]);
Effects::BasicFX->SetDiffuseMap(DiffuseMapSRV[i]);
 
   activeTech->GetPassByIndex(p)->Apply(0, pDeviceContext);
 
   mModel.Mesh.Draw(i);
   }
}
 
}
 
 
MeshGeometry::MeshGeometry()
{
VertexBuffer = nullptr;
IndexBuffer = nullptr;
 
IndexBufferFormat = DXGI_FORMAT_R16_UINT;
VertexStride = 0;
}
 
MeshGeometry::~MeshGeometry()
{
ReleaseCOM(VertexBuffer);
ReleaseCOM(IndexBuffer);
}
 
void MeshGeometry::SetIndices(const USHORT* indices, UINT count)
{
D3D11_BUFFER_DESC ibd;
    ibd.Usage = D3D11_USAGE_IMMUTABLE;
    ibd.ByteWidth = sizeof(USHORT) * count;
    ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
    ibd.CPUAccessFlags = 0;
    ibd.MiscFlags = 0;
ibd.StructureByteStride = 0;
 
    D3D11_SUBRESOURCE_DATA iinitData;
    iinitData.pSysMem = indices;
 
HR(pDevice->CreateBuffer(&ibd, &iinitData, &IndexBuffer));
}
 
void MeshGeometry::SetSubsetTable(std::vector<Subset>& subsetTable)
{
SubsetTable = subsetTable;
}
 
void MeshGeometry::Draw(UINT subsetId)
{
    UINT offset = 0;
 
pDeviceContext->IASetVertexBuffers(0, 1, &VertexBuffer, &VertexStride, &offset);
pDeviceContext->IASetIndexBuffer(IndexBuffer, IndexBufferFormat, 0);
 
pDeviceContext->DrawIndexed(SubsetTable[subsetId].FaceCount * 3, SubsetTable[subsetId].FaceStart * 3,  0);
}
 
 
template <typename VertexType>
void MeshGeometry::SetVertices(const VertexType* vertices, UINT count)
{
ReleaseCOM(VertexBuffer);
 
VertexStride = sizeof(VertexType);
 
D3D11_BUFFER_DESC vbd;
    vbd.Usage = D3D11_USAGE_IMMUTABLE;
vbd.ByteWidth = sizeof(VertexType) * count;
    vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    vbd.CPUAccessFlags = 0;
    vbd.MiscFlags = 0;
vbd.StructureByteStride = 0;
 
    D3D11_SUBRESOURCE_DATA vinitData;
    vinitData.pSysMem = vertices;
 
HR(pDevice->CreateBuffer(&vbd, &vinitData, &VertexBuffer));
}
Edited by newtechnology

Share this post


Link to post
Share on other sites


I only had a quick look at your code, but instead of
vbd.ByteWidth = sizeof(Vertex::Basic32)*numVertices // num verts found in the last mesh
you probably want:
vbd.ByteWidth = sizeof(Vertex::Basic32)*vertices.size() // num verts total

 

Thanks that was the problem . Feeling really stupid mellow.png what kinda mistake was that mellow.png . The mesh has been imported but still faulty.

 

 

 

My directx 11 model loader using assimp. (I've gone through a lot of problems in model loading so give credits to me and other people (Richard software website's author, Frank .D luna and mrbeans22 (or something like that)) if you use this.)

Thanks newtechnology for your code . I have read their book, website and code. The code Richard had was in c# and It was really hard I'll give your code a try . And ask you if I do not understand . Thanks
 

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!