Skip to main content
GameDev.net gamedev.net
🔒 Locked

Load and render MS3D file problem in DX11

Started by pnt1614 Jan 10, 2013 at 2:05 AM 1 replies 2.1k views
Original Post
pnt1614
pnt1614

I am trying to load and render a MS3D file in DX11 but there is a problem that texture coordinate does not match as well as the object looks like be triangulated. The left image is rendered with DX11, and the other is opened with Milkshape 3D.

loadandrenderams3dmesh.jpgahouseusemilkshape3d.jpg

In the source code, I try to convert to LHS such as: index, z coordinate, normal vector, it has not worked.


HRESULT MeshHandler::LoadMS3DFile( std::wstring filename, ID3D11Device* pd3dDevice ) {
	#pragma region local variables
	// Temporary Milkshape structures
	unsigned short usVertexCount = 0;
	unsigned short usTriangleCount = 0;
	unsigned short usGroupCount = 0;
	unsigned short usMaterialCount = 0;

	MS3DVertex* pMS3DVertices = NULL;
	MS3DTriangle* pMS3DTriangles = NULL;
	MS3DGroup* pMS3DGroups = NULL;
	MS3DMaterial* pMS3DMaterials = NULL;

	std::ifstream fin;
	MS3DHeader header;
	#pragma endregion

	// Open the file and read the MS3D header data
	fin.open( filename.c_str(),std::ios::binary );
	fin.read((char*)(&(header.id)), sizeof(header.id));
	fin.read((char*)(&(header.version)), sizeof(header.version));
	if (header.version!=3 && header.version!=4)
		return NULL;

	#pragma region Load all the vertices
	fin.read((char*)(&usVertexCount), sizeof(unsigned short));
	pMS3DVertices = new MS3DVertex[usVertexCount];
	m_NumOfVertices = usVertexCount;
	for (int i = 0; i < usVertexCount; i++)
	{
		fin.read((char*)&(pMS3DVertices[i].flags), sizeof(unsigned char));
		fin.read((char*)&(pMS3DVertices[i].vertex[0]), sizeof(float));
		fin.read((char*)&(pMS3DVertices[i].vertex[1]), sizeof(float));
		fin.read((char*)&(pMS3DVertices[i].vertex[2]), sizeof(float));
		fin.read((char*)&(pMS3DVertices[i].boneId), sizeof(char));
		fin.read((char*)&(pMS3DVertices[i].referenceCount), sizeof(unsigned char));
	}
	#pragma endregion

	#pragma region Load all the triangle indices
	fin.read((char*)(&usTriangleCount), sizeof(unsigned short));
	if (usTriangleCount >0)
	{
		pMS3DTriangles = new MS3DTriangle[usTriangleCount];
		if (pMS3DTriangles != NULL)
		{
			m_NumOfTriangles = usTriangleCount;
			for (int i = 0; i < usTriangleCount; i++)
			{
				fin.read((char*)&(pMS3DTriangles[i].flags),sizeof(unsigned short));

				fin.read((char*)&(pMS3DTriangles[i].vertexIndices[0]), sizeof(unsigned short)); //3*sizeof(unsigned short));
				fin.read((char*)&(pMS3DTriangles[i].vertexIndices[1]), sizeof(unsigned short)); //3*sizeof(unsigned short));
				fin.read((char*)&(pMS3DTriangles[i].vertexIndices[2]), sizeof(unsigned short)); //3*sizeof(unsigned short));
				fin.read((char*)&(pMS3DTriangles[i].vertexNormals[0]), 3*sizeof(float));
				fin.read((char*)&(pMS3DTriangles[i].vertexNormals[1]), 3*sizeof(float));
				fin.read((char*)&(pMS3DTriangles[i].vertexNormals[2]), 3*sizeof(float));
				fin.read((char*)&(pMS3DTriangles[i].s), 3*sizeof(float));
				fin.read((char*)&(pMS3DTriangles[i].t), 3*sizeof(float));
				fin.read((char*)&(pMS3DTriangles[i].smoothingGroup), sizeof(unsigned char));
				fin.read((char*)&(pMS3DTriangles[i].groupIndex), sizeof(unsigned char));
			}
		}		
	}	
	#pragma endregion

	#pragma region Load all the group information
	fin.read((char*)(&usGroupCount), sizeof(unsigned short));
	if (usGroupCount > 0)  
	{
		pMS3DGroups = new MS3DGroup[usGroupCount];
		if (pMS3DGroups != NULL)
		{
			m_NumOfGroups = usGroupCount;
			m_pGroups = new Group[m_NumOfGroups];
			if (m_pGroups != NULL)
			{
				for (int i = 0; i < usGroupCount; i++)
				{
					fin.read((char*)&(pMS3DGroups[i].flags), sizeof(unsigned char));
					fin.read((char*)&(pMS3DGroups[i].name), sizeof(char[32]));
					fin.read((char*)&(pMS3DGroups[i].numtriangles), sizeof(unsigned short));
					unsigned short triCount = pMS3DGroups[i].numtriangles;
					pMS3DGroups[i].triangleIndices = new unsigned short[triCount];
					fin.read((char*)(pMS3DGroups[i].triangleIndices), sizeof(unsigned short) * triCount);
					fin.read((char*)&(pMS3DGroups[i].materialIndex), sizeof(char));

					m_pGroups[i].m_MaterialIndex = pMS3DGroups[i].materialIndex;
					m_pGroups[i].m_NumTriangles = pMS3DGroups[i].numtriangles;
					m_pGroups[i].m_pTriangleIndices = new unsigned short[triCount];
					memcpy(m_pGroups[i].m_pTriangleIndices, pMS3DGroups[i].triangleIndices, sizeof(unsigned short) * triCount );
				}
			}			
		}		
	}	
	#pragma endregion

	#pragma region Load all the material information
	fin.read((char*)(&usMaterialCount),sizeof(unsigned short));

	if (usMaterialCount > 0) 
	{
		pMS3DMaterials = new MS3DMaterial[usMaterialCount];
		m_NumOfMaterials = usMaterialCount;
		m_pMaterials = new Material[m_NumOfMaterials];
		if (pMS3DMaterials != NULL && m_pMaterials != NULL)
		{			
			for (int i = 0; i < m_NumOfMaterials; i++)
			{
				fin.read((char*)&(pMS3DMaterials[i].name), sizeof(char[32]));
				fin.read((char*)&(pMS3DMaterials[i].ambient), 4 * sizeof(float));
				fin.read((char*)&(pMS3DMaterials[i].diffuse), 4 * sizeof(float));
				fin.read((char*)&(pMS3DMaterials[i].specular), 4 * sizeof(float));
				fin.read((char*)&(pMS3DMaterials[i].emissive), 4 * sizeof(float));
				fin.read((char*)&(pMS3DMaterials[i].shininess), sizeof(float));
				fin.read((char*)&(pMS3DMaterials[i].transparency), sizeof(float));
				fin.read((char*)&(pMS3DMaterials[i].mode), sizeof(char));
				fin.read((char*)&(pMS3DMaterials[i].texture), sizeof(char[128]));
				fin.read((char*)&(pMS3DMaterials[i].alphamap), sizeof(char[128]));

				memcpy(m_pMaterials[i].m_ambient, pMS3DMaterials[i].ambient, sizeof(float)*4);
				memcpy(m_pMaterials[i].m_diffuse, pMS3DMaterials[i].diffuse, sizeof(float)*4);
				memcpy(m_pMaterials[i].m_emissive, pMS3DMaterials[i].emissive, sizeof(float)*4);				
				memcpy(m_pMaterials[i].m_specular, pMS3DMaterials[i].specular, sizeof(float)*4);
				m_pMaterials[i].m_shininess = pMS3DMaterials[i].shininess;

				m_pMaterials[i].m_filename_length = strlen(pMS3DMaterials[i].texture) + 1;
				strcpy(m_pMaterials[i].m_pTextureFilename, pMS3DMaterials[i].texture);
			}
		}
	}
	#pragma endregion

	// Close the file (remaining file data unused)
	fin.close();

	//-----------------------------------------------------------------------------------------------------
	// Swap the 2nd and the 3rd indices
	//-----------------------------------------------------------------------------------------------------
	for (int i=0; i<m_NumOfTriangles; i++)
	{
		unsigned short temp = pMS3DTriangles[i].vertexIndices[1];
		pMS3DTriangles[i].vertexIndices[1] = pMS3DTriangles[i].vertexIndices[2];
		pMS3DTriangles[i].vertexIndices[2] = temp;
	}

	//-----------------------------------------------------------------------------------------------------
	#pragma region
	//Create an array of vertices for generating a new vertex buffer
	m_NumOfVertices = m_NumOfTriangles * 3;
	m_pRenderVertices = new D3DVERTEX[m_NumOfVertices];
	UINT iCount = 0;
	for ( int i=0; i<m_NumOfGroups; i++ ) 
	{
		m_pGroups[i].m_VertexStart = iCount;		
		for ( int j=0; j<m_pGroups[i].m_NumTriangles; j++ ) 
		{
			int iTriangleIndex = pMS3DGroups[i].triangleIndices[j];
			for ( int k=0; k<3; k++ )	
			{
				float vx = pMS3DVertices[pMS3DTriangles[iTriangleIndex].vertexIndices[k]].vertex[0];
				float vy = pMS3DVertices[pMS3DTriangles[iTriangleIndex].vertexIndices[k]].vertex[1];
				float vz = pMS3DVertices[pMS3DTriangles[iTriangleIndex].vertexIndices[k]].vertex[2] * -1.0f;
				m_pRenderVertices[iCount].pos = D3DXVECTOR3(vx, vy, vz);;

				float nx = pMS3DTriangles[iTriangleIndex].vertexNormals[k][0];
				float ny = pMS3DTriangles[iTriangleIndex].vertexNormals[k][1];
				float nz = pMS3DTriangles[iTriangleIndex].vertexNormals[k][2] * -1.0f;				
				m_pRenderVertices[iCount].normal = D3DXVECTOR3(nx, ny, nz);

				float u = pMS3DTriangles[iTriangleIndex].s[k]; 
				float v = pMS3DTriangles[iTriangleIndex].t[k];				
				m_pRenderVertices[iCount].tex = D3DXVECTOR2(u, v);

				++iCount;
			}
		}
		m_pGroups[i].m_NumOfVertices = iCount - m_pGroups[i].m_VertexStart;
	}
	

	//-----------------------------------------------------------------------------------------------------
	//Create an index array
	//Did not test yet.
	iCount = 0;
	UINT NumOfIndices = m_NumOfTriangles * 3;
	m_pRenderIndices = new int[NumOfIndices];
	for ( int i=0; i<m_NumOfGroups; i++ ) 
	{
		m_pGroups[i].m_IndexStart = iCount;
		for ( int j=0; j<m_pGroups[i].m_NumTriangles; j++ ) 
		{			
			for ( int k=0; k<3; k++ )	
			{				
				m_pRenderIndices[iCount] = j*3 + k;
				++iCount;
			}
		}
		m_pGroups[i].m_IndexCount = iCount - m_pGroups[i].m_IndexStart;
	}
	#pragma endregion

	//-----------------------------------------------------------------------------------------------------
	// Releasing
	//-----------------------------------------------------------------------------------------------------
	if (pMS3DMaterials != NULL)
	{
		delete []pMS3DMaterials;
		pMS3DMaterials = NULL;
	}

	if (pMS3DGroups != NULL)
	{
		for (int i = 0; i < usGroupCount; i++)
		{
			if (pMS3DGroups[i].triangleIndices != NULL)
			{
				delete []pMS3DGroups[i].triangleIndices;
				pMS3DGroups[i].triangleIndices = NULL;
			}
		}
		delete []pMS3DGroups;
		pMS3DGroups = NULL;
	}

	if (pMS3DTriangles != NULL)
	{
		delete[] pMS3DTriangles;
		pMS3DTriangles = NULL;
	}
	
	if (pMS3DVertices != NULL)
	{
		delete []pMS3DVertices;
		pMS3DVertices = NULL;
	}

	return S_OK;
}

Anybody helps me, please. Thank in advance

Jason Z
Jason Z

I would offer for you to take a look at my geometry loader class from Hieroglyph 3, but I think you are already aware of it... Have you verified if there is an issue on all of the vertices, or is it only some of them? I would recommend to do a frame grab with PIX and then compare the vertex data that you have with what you find in the Milkshape3D editor (IIRC there is a way to look at the raw data via the editor itself).

Jason Zink :: DirectX MVP   Direct3D 11 engine on CodePlex: Hieroglyph 3 Direct3D Books: 
pnt1614
pnt1614

Thank for helping me, Jason Z. I have already looked at you geometry loader class and figured out the reason. We just comment the following lines:


for (int i=0; i<m_NumOfTriangles; i++)
	{
		unsigned short temp = pMS3DTriangles[i].vertexIndices[1];
		pMS3DTriangles[i].vertexIndices[1] = pMS3DTriangles[i].vertexIndices[2];
		pMS3DTriangles[i].vertexIndices[2] = temp;
	}

and we do not need to inverse z value.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.