3D Model Loading Problems

Started by
25 comments, last by ryan20fun 9 years, 6 months ago

I’ve posted a link where you can read all about it.

I’ve never loaded a .OBJ file, so I can’t advise you beyond what the link already explains.

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Advertisement

I’ve posted a link where you can read all about it.

I’ve never loaded a .OBJ file, so I can’t advise you beyond what the link already explains.


L. Spiro

what are you working with for 3d models?

It is typical to see corrupted geometry when programming object importers / exporters. Winding order is the simplest of the problems to solve. Typically invalid output is result of triangles indexing wrong vertices.

Cheers!

I know that. But how could a professional 3d software give wrong indices or vertices?
By the way, vs2012 model view failed to load the obj exported by max. But it worked well with blender's.
The 3D CAD tool 99 times out of 100 produces valid file(albit with there own tweak on some formats like DAE, wavefront object )
The problem most likely exists in your parser code, It is also posible that the CAD tool has produced a edge case with the file.

I would recomend that you use a tool like Assimp to do the heavy lifting for you and you just process the data from it.
It's what i do, And it saves me from the hassle of different 3D formats as it handles a nice variety of them.

Hope that helps smile.png
i don't know much about assimp.but i think i will have to go there some day. Is there any tutorial about assimp with d3d? If not , gl is fine

This ought to get you started.

If you need more help just ask, Or if you want I could post the code I am currently using(but that will change after some time next month due to grabage output when using multiple objects but I am sure that has to do with how I am handling the vertices though... )

Never say Never, Because Never comes too soon. - ryan20fun

Disclaimer: Each post of mine is intended as an attempt of helping and/or bringing some meaningfull insight to the topic at hand. Due to my nature, my good intentions will not always be plainly visible. I apologise in advance and assure you I mean no harm and do not intend to insult anyone.

I’ve posted a link where you can read all about it.

I’ve never loaded a .OBJ file, so I can’t advise you beyond what the link already explains.


L. Spiro

what are you working with for 3d models?

The FBX SDK.

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

It is typical to see corrupted geometry when programming object importers / exporters. Winding order is the simplest of the problems to solve. Typically invalid output is result of triangles indexing wrong vertices.

Cheers!

I know that. But how could a professional 3d software give wrong indices or vertices?

By the way, vs2012 model view failed to load the obj exported by max. But it worked well with blender's.

The 3D CAD tool 99 times out of 100 produces valid file(albit with there own tweak on some formats like DAE, wavefront object )

The problem most likely exists in your parser code, It is also posible that the CAD tool has produced a edge case with the file.

I would recomend that you use a tool like Assimp to do the heavy lifting for you and you just process the data from it.

It's what i do, And it saves me from the hassle of different 3D formats as it handles a nice variety of them.

Hope that helps smile.png

aaaaaahhhhhhhhh!!!!!!!!!! I'm going crazy X(

I just don't know why it always doesn't give me the right result. though i use assimp for the data things,i'm still getting something like this

MIeoy16.jpg



bool LoadModel(const std::string &fileName, 
			   std::vector<XMFLOAT3> &positions,
			   std::vector<XMFLOAT3> &normals,
			   std::vector<XMFLOAT2> &texcoords,
			   std::vector<unsigned int> &posIndices,
			   std::vector<unsigned int> &norIndices,
			   std::vector<unsigned int> &uvIndices){
	Assimp::Importer importer;
	const aiScene* scene = importer.ReadFile(fileName,aiProcess_Triangulate|aiProcess_GenNormals);
	
	unsigned int numMeshes = scene->mNumMeshes;
	unsigned int numVertices = 0,numIndices = 0;
	for (unsigned int MeshIndex = 0; MeshIndex<numMeshes;MeshIndex++)
	{
		aiMesh *mesh = scene->mMeshes[MeshIndex];
	
		numIndices += mesh->mNumFaces*3;	
		for (unsigned int VertexIndex = 0;VertexIndex<mesh->mNumVertices;VertexIndex++)
		{
			XMFLOAT3 vertex,normal;
			XMFLOAT2 texcoord;

			vertex.x = mesh->mVertices[VertexIndex].x;
			vertex.y = mesh->mVertices[VertexIndex].y;
			vertex.z = mesh->mVertices[VertexIndex].z;
			
			normal.x = mesh->mNormals[VertexIndex].x;
			normal.y = mesh->mNormals[VertexIndex].y;
			normal.z = mesh->mNormals[VertexIndex].z;
// 
// 			char buffer[128];
// 			float tc = mesh->mTextureCoords[VertexIndex]->x;
// 			sprintf_s(buffer,"%f",tc);
// 			texcoord.x = mesh->mTextureCoords[VertexIndex]->x;
// 			texcoord.y = mesh->mTextureCoords[VertexIndex]->y;

			positions.push_back(vertex);
			normals.push_back(normal);
			texcoords.push_back(texcoord);
		}

		unsigned int loop_index = 0;
		for (unsigned int FaceIndex = 0;FaceIndex<mesh->mNumFaces;FaceIndex++)
		{
			const aiFace& face = mesh->mFaces[FaceIndex];
			posIndices.push_back(face.mIndices[0]);
			posIndices.push_back(face.mIndices[1]);
			posIndices.push_back(face.mIndices[2]);
		}
	}

	numIndices = posIndices.size();
	numVertices += positions.size();

// 	char vertexCount[128];
// 	sprintf_s(vertexCount,"%i",numVertices);
// 	MessageBoxA(0,vertexCount,0,0);
	return true;
}

Perhaps you should consider that it could be related to how to draw the object, not how you load it.

I would suggest posting the code for creating the vertex-buffer layout etc.

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

It is typical to see corrupted geometry when programming object importers / exporters. Winding order is the simplest of the problems to solve. Typically invalid output is result of triangles indexing wrong vertices.

Cheers!

I know that. But how could a professional 3d software give wrong indices or vertices?

By the way, vs2012 model view failed to load the obj exported by max. But it worked well with blender's.

The 3D CAD tool 99 times out of 100 produces valid file(albit with there own tweak on some formats like DAE, wavefront object )

The problem most likely exists in your parser code, It is also posible that the CAD tool has produced a edge case with the file.

I would recomend that you use a tool like Assimp to do the heavy lifting for you and you just process the data from it.

It's what i do, And it saves me from the hassle of different 3D formats as it handles a nice variety of them.

Hope that helps smile.png

aaaaaahhhhhhhhh!!!!!!!!!! I'm going crazy X(

I just don't know why it always doesn't give me the right result. though i use assimp for the data things,i'm still getting something like this

MIeoy16.jpg



bool LoadModel(const std::string &fileName, 
			   std::vector<XMFLOAT3> &positions,
			   std::vector<XMFLOAT3> &normals,
			   std::vector<XMFLOAT2> &texcoords,
			   std::vector<unsigned int> &posIndices,
			   std::vector<unsigned int> &norIndices,
			   std::vector<unsigned int> &uvIndices){
	Assimp::Importer importer;
	const aiScene* scene = importer.ReadFile(fileName,aiProcess_Triangulate|aiProcess_GenNormals);
	
	unsigned int numMeshes = scene->mNumMeshes;
	unsigned int numVertices = 0,numIndices = 0;
	for (unsigned int MeshIndex = 0; MeshIndex<numMeshes;MeshIndex++)
	{
		aiMesh *mesh = scene->mMeshes[MeshIndex];
	
		numIndices += mesh->mNumFaces*3;	
		for (unsigned int VertexIndex = 0;VertexIndex<mesh->mNumVertices;VertexIndex++)
		{
			XMFLOAT3 vertex,normal;
			XMFLOAT2 texcoord;

			vertex.x = mesh->mVertices[VertexIndex].x;
			vertex.y = mesh->mVertices[VertexIndex].y;
			vertex.z = mesh->mVertices[VertexIndex].z;
			
			normal.x = mesh->mNormals[VertexIndex].x;
			normal.y = mesh->mNormals[VertexIndex].y;
			normal.z = mesh->mNormals[VertexIndex].z;
// 
// 			char buffer[128];
// 			float tc = mesh->mTextureCoords[VertexIndex]->x;
// 			sprintf_s(buffer,"%f",tc);
// 			texcoord.x = mesh->mTextureCoords[VertexIndex]->x;
// 			texcoord.y = mesh->mTextureCoords[VertexIndex]->y;

			positions.push_back(vertex);
			normals.push_back(normal);
			texcoords.push_back(texcoord);
		}

		unsigned int loop_index = 0;
		for (unsigned int FaceIndex = 0;FaceIndex<mesh->mNumFaces;FaceIndex++)
		{
			const aiFace& face = mesh->mFaces[FaceIndex];
			posIndices.push_back(face.mIndices[0]);
			posIndices.push_back(face.mIndices[1]);
			posIndices.push_back(face.mIndices[2]);
		}
	}

	numIndices = posIndices.size();
	numVertices += positions.size();

// 	char vertexCount[128];
// 	sprintf_s(vertexCount,"%i",numVertices);
// 	MessageBoxA(0,vertexCount,0,0);
	return true;
}

Have you tried a graphics debugger?

There are some options:

D3D SDK - PiX

nVidia - NSight

AMD - GPUPerfStudio

VS 2012/2013 (Pro+)

Perhaps you should consider that it could related to how to draw the object, not how you load it.

I would suggest posting the code for creating the vertex-buffer layout etc.

L. Spiro

Seconded.

HTH.

Never say Never, Because Never comes too soon. - ryan20fun

Disclaimer: Each post of mine is intended as an attempt of helping and/or bringing some meaningfull insight to the topic at hand. Due to my nature, my good intentions will not always be plainly visible. I apologise in advance and assure you I mean no harm and do not intend to insult anyone.


Have you tried a graphics debugger?
There are some options:
D3D SDK - PiX
nVidia - NSight
AMD - GPUPerfStudio
VS 2012/2013 (Pro+)

I'm new to these things so I don't know anything about what you've mentioned above...

Basically there's nothing about how to debugger an application but just to implement them on most directx tutorial website.


struct SimpleVertex
{
    XMFLOAT3 Pos;
    XMFLOAT3 Color;
};

So that's my SimpleVertex


    // Compile the vertex shader
    ID3DBlob* pVSBlob = NULL;
    hr = CompileShaderFromFile( L"Model Loading.fx", "VS", "vs_4_0", &pVSBlob );
    if( FAILED( hr ) )
    {
        MessageBox( NULL,
                    L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
        return hr;
    }

	// Create the vertex shader
	hr = g_pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &g_pVertexShader );
	if( FAILED( hr ) )
	{	
		pVSBlob->Release();
        return hr;
	}

    // Define the input layout
    D3D11_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
	};
	UINT numElements = ARRAYSIZE( layout );

    // Create the input layout
	hr = g_pd3dDevice->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(),
                                          pVSBlob->GetBufferSize(), &g_pVertexLayout );
	pVSBlob->Release();
	if( FAILED( hr ) )
        return hr;

    // Set the input layout
    g_pImmediateContext->IASetInputLayout( g_pVertexLayout );

	// Compile the pixel shader
	ID3DBlob* pPSBlob = NULL;
    hr = CompileShaderFromFile( L"Model Loading.fx", "PS", "ps_4_0", &pPSBlob );
    if( FAILED( hr ) )
    {
        MessageBox( NULL,
                    L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
        return hr;
    }

	// Create the pixel shader
	hr = g_pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &g_pPixelShader );
	pPSBlob->Release();
    if( FAILED( hr ) )
        return hr;

	std::vector<XMFLOAT3> aiPos,aiNor;
	std::vector<XMFLOAT2> aiUV;
	std::vector<unsigned int> posIndices,norIndices,uvIndices;
	LoadModel("cube.obj",aiPos,aiNor,aiUV,posIndices,norIndices,uvIndices);
	g_numIndices = posIndices.size();
	for (unsigned int i = 0;i < aiPos.size();i++)
	{
		SimpleVertex vertex;
		vertex.Pos = aiPos[i];
		vertex.Color = aiPos[i];
		m_vertices.push_back(vertex);
	}
    D3D11_BUFFER_DESC bd;
	ZeroMemory( &bd, sizeof(bd) );
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( SimpleVertex ) * m_vertices.size();
    bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	bd.CPUAccessFlags = 0;
    D3D11_SUBRESOURCE_DATA InitData;
	ZeroMemory( &InitData, sizeof(InitData) );
    InitData.pSysMem = &m_vertices[0];
    hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
    if( FAILED( hr ) )
        return hr;

    // Set vertex buffer
    UINT stride = sizeof( SimpleVertex );
    UINT offset = 0;
    g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset );

    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( unsigned int ) * posIndices.size();        // 36 vertices needed for 12 triangles in a triangle list
    bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
	bd.CPUAccessFlags = 0;
    InitData.pSysMem = &posIndices[0];
    hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pIndexBuffer );
    if( FAILED( hr ) )
        return hr;

I don't see anything wrong with those

bd.ByteWidth = sizeof( unsigned int ) * posIndices.size(); // 36 vertices needed for 12 triangles in a triangle list

That could be your problem, You should only hard code values for basic testing or when lazy.

Try changing that to three(assuming that there are only three vertices).

And what do you intend to do with: "posIndices", norIndices, uvIndices?

HTH

Never say Never, Because Never comes too soon. - ryan20fun

Disclaimer: Each post of mine is intended as an attempt of helping and/or bringing some meaningfull insight to the topic at hand. Due to my nature, my good intentions will not always be plainly visible. I apologise in advance and assure you I mean no harm and do not intend to insult anyone.

This topic is closed to new replies.

Advertisement